Main menu¶
How do I control which menu items are shown for a user?¶
Using include
you can control which menu items are shown for a given user. This also controls access, so you can know that your menu and your access control are always in sync.
menu = MainMenu(
items=dict(
albums=M(
view=albums_view,
),
artists=M(
view=artists_view,
include=lambda user, **_: user.is_staff,
),
),
)
How do I control the display name of a menu item?¶
By default the display name is derived from the name
of the M
object. So given:
menu = MainMenu(
items=dict(
albums=M(view=albums_view),
),
)
The name
would be “albums”, and the display name is automatically derived as “Albums”. The translation from name
to display_name
replaces _
with space, runs gettext_lazy()
on the result, and then capitalizes that.
If you want to do something else, pass the display_name
parameter:
menu = MainMenu(
items=dict(
albums=M(
view=albums_view,
display_name=gettext_lazy('Discography'),
),
),
)
Note that display_name
can be a function too.
How do I add sub-paths for a menu item?¶
Since the menu system can control access, it is useful to nest path mappings under a specific menu item without showing them in the menu. This is done with the paths
argument:
menu = MainMenu(
items=dict(
albums=M(
view=albums_view,
paths=[
path('<album_pk>/edit/', edit_album_view),
],
),
),
)
How do I add external links in the menu?¶
Use the special value EXTERNAL
for the view
argument, and use url
argument:
menu = MainMenu(
items=dict(
albums=M(
view=EXTERNAL,
url='https://docs.iommi.rocks',
),
),
)
Note the icon added by default for an external link. This is configurable via the icon_formatter
on your Style
.
How do I nest menu items?¶
You can create a menu hierarchy with the items
argument, which produces expandable sections. iommi will open the menu items that matches the current URL by default. You can also force a submenu to be open with the open
argument:
menu = MainMenu(
items=dict(
things=M(
view=things_view,
open=True, # force open
items=dict(
albums=M(
view=albums_view,
),
artists=M(
view=artists_view,
)
),
),
),
)
The open
argument can be a callable.
How do I put arbitrary html in the menu?¶
With the template
argument you can put arbitrary html into menu items:
menu = MainMenu(
items=dict(
albums=M(
view=EXTERNAL,
template=Template('''
<li style="margin-left: 1rem">
<span style="display: inline-block; width: 1.5rem; background: red; border-radius: 50%"> </span>
<span style="display: inline-block; width: 1.5rem; background: orange; border-radius: 50%"> </span>
<span style="display: inline-block; width: 1.5rem; background: yellow; border-radius: 50%"> </span>
<span style="display: inline-block; width: 1.5rem; background: green; border-radius: 50%"> </span>
<span style="display: inline-block; width: 1.5rem; background: blue; border-radius: 50%"> </span>
</li>
''')
),
),
)
Note that you want to include the <li>
tag.
You can also override the base template via your Style
.
How do I show which specific object I am on in the menu?¶
If you have a list of objects and you click into one of them, you might want to show that item in the menu, and potentially also sub-pages for that item. You do that by using iommi path decoders, and mapping everything together with display_name
, path
, params
and url
:
menu = MainMenu(
items=dict(
albums=M(
view=albums_view,
items=dict(
album=M(
view=album_view,
display_name=lambda album, **_: str(album),
path='<album_pk>/',
params={'album'},
url=lambda album, **_: f'/albums/{album.pk}/',
),
)
),
),
)