So far, we have been entering URLs manually to access our plugin views. That works for development, but it is not very friendly for regular use. In this step, we will add links to the NetBox navigation menu so users can reach our pages with a click.
🟦 Note: If you skipped the previous step and you cloned netbox-plugin-demo, run git checkout step07-templates.
Begin by creating navigation.py in the netbox_access_lists/ directory of your plugin project root.
cd netbox_access_lists/
touch navigation.pyWe will use NetBox's navigation classes to add menu items and optional buttons:
PluginMenuItemfor menu linksPluginMenufor grouping links under a plugin sectionPluginMenuButtonfor shortcut buttons (for example, Add)
At the top of the file, import the navigation classes provided by NetBox:
from netbox.plugins import PluginMenu, PluginMenuButton, PluginMenuItemWe will add a link to the list view for each model. This is done by creating a PluginMenuItem with (at minimum) two arguments:
linkis the name of the URL we want to link tolink_textis the text shown in the menu
Create two PluginMenuItem objects and assign them to accesslist_item and accesslistrule_item:
# Access List
accesslist_item = PluginMenuItem(
link='plugins:netbox_access_lists:accesslist_list',
link_text='Access Lists',
)
# Access List Rule
accesslistrule_item = PluginMenuItem(
link='plugins:netbox_access_lists:accesslistrule_list',
link_text='Access List Rules',
)Next, we will group our items under a single plugin menu section. We will:
- label the plugin menu
Access Lists - create two groups,
Access ListsandRules - use a lock icon for the menu section
Add this to the end of navigation.py:
menu = PluginMenu(
label='Access Lists',
groups=(
(
'Access Lists',
(accesslist_item,),
),
(
'Rules',
(accesslistrule_item,),
),
),
icon_class='mdi mdi-lock',
)When you reload NetBox, you should see a new Access Lists section appear in the navigation menu with the two links.
🟦 Note: If the menu items do not appear, restart the development server (manage.py runserver) and refresh the page.
We can also add buttons to the menu items, which is handy for quick access to add forms.
A PluginMenuButton supports:
linkis the URL name the button should opentitleis the tooltip text shown on hovericon_classcontrols the icon that is displayed
Create button lists above the PluginMenuItem definitions:
accesslist_buttons = [
PluginMenuButton(
link='plugins:netbox_access_lists:accesslist_add',
title='Add',
icon_class='mdi mdi-plus-thick',
)
]
accesslistrule_buttons = [
PluginMenuButton(
link='plugins:netbox_access_lists:accesslistrule_add',
title='Add',
icon_class='mdi mdi-plus-thick',
)
]Then attach them to the menu items using the buttons argument:
# Access List
accesslist_item = PluginMenuItem(
link='plugins:netbox_access_lists:accesslist_list',
link_text='Access Lists',
buttons=accesslist_buttons,
)
# Access List Rule
accesslistrule_item = PluginMenuItem(
link='plugins:netbox_access_lists:accesslistrule_list',
link_text='Access List Rules',
buttons=accesslistrule_buttons,
)Now you should see a plus icon appear next to each menu item while hovering.
🟦 Note: Menu buttons are only shown while hovering over a menu item.
Although permissions are not fully covered in this tutorial, we can still add basic permission constraints so menu items and buttons only appear for users who are allowed to use them.
To do this, add the permissions argument to both PluginMenuItem and PluginMenuButton.
Permission strings follow the format app_label.codename, for example:
netbox_access_lists.view_accesslistnetbox_access_lists.add_accesslist
# Access List
accesslist_buttons = [
PluginMenuButton(
link='plugins:netbox_access_lists:accesslist_add',
title='Add',
icon_class='mdi mdi-plus-thick',
permissions=['netbox_access_lists.add_accesslist'],
)
]
# Access List Rule
accesslistrule_buttons = [
PluginMenuButton(
link='plugins:netbox_access_lists:accesslistrule_add',
title='Add',
icon_class='mdi mdi-plus-thick',
permissions=['netbox_access_lists.add_accesslistrule'],
)
]# Access List
accesslist_item = PluginMenuItem(
link='plugins:netbox_access_lists:accesslist_list',
link_text='Access Lists',
permissions=['netbox_access_lists.view_accesslist'],
buttons=accesslist_buttons,
)
# Access List Rule
accesslistrule_item = PluginMenuItem(
link='plugins:netbox_access_lists:accesslistrule_list',
link_text='Access List Rules',
permissions=['netbox_access_lists.view_accesslistrule'],
buttons=accesslistrule_buttons,
)Your complete navigation.py should now look like this:
from netbox.plugins import PluginMenu, PluginMenuButton, PluginMenuItem
#
# Define plugin menu buttons
#
# Access List
accesslist_buttons = [
PluginMenuButton(
link='plugins:netbox_access_lists:accesslist_add',
title='Add',
icon_class='mdi mdi-plus-thick',
permissions=['netbox_access_lists.add_accesslist'],
)
]
# Access List Rule
accesslistrule_buttons = [
PluginMenuButton(
link='plugins:netbox_access_lists:accesslistrule_add',
title='Add',
icon_class='mdi mdi-plus-thick',
permissions=['netbox_access_lists.add_accesslistrule'],
)
]
#
# Define plugin menu items
#
# Access List
accesslist_item = PluginMenuItem(
link='plugins:netbox_access_lists:accesslist_list',
link_text='Access Lists',
permissions=['netbox_access_lists.view_accesslist'],
buttons=accesslist_buttons,
)
# Access List Rule
accesslistrule_item = PluginMenuItem(
link='plugins:netbox_access_lists:accesslistrule_list',
link_text='Access List Rules',
permissions=['netbox_access_lists.view_accesslistrule'],
buttons=accesslistrule_buttons,
)
#
# Define plugin menu groups
#
menu = PluginMenu(
label='Access Lists',
groups=(
(
'Access Lists',
(accesslist_item,),
),
(
'Rules',
(accesslistrule_item,),
),
),
icon_class='mdi mdi-lock',
)For reference, your plugin project should now include navigation.py:
.
├── netbox_access_lists
│ ├── choices.py
│ ├── forms.py
│ ├── __init__.py
│ ├── migrations
│ │ ├── 0001_initial.py
│ │ └── __init__.py
│ ├── models.py
│ ├── navigation.py
│ ├── tables.py
│ ├── templates
│ │ └── netbox_access_lists
│ │ ├── accesslist.html
│ │ └── accesslistrule.html
│ ├── urls.py
│ └── views.py
├── pyproject.toml
└── README.md
⬅️ Step 7: Templates | Step 9: Filter Sets ➡️

