Navutils represents menus using Menu and Node instances, each menu being a collection of
node instances representing a menu link. Nodes may have children, which are also Node instances.

Let’s see a minimal example.

yourapp/menu.py:

fromnavutilsimportmenumain_menu=menu.Menu('main')menu.register(main_menu)# will be shown to everybodyblog=menu.Node(id='blog',label='Blog',pattern_name='blog:index')main_menu.register(blog)# nodes created with a pattern_name argument will use django reverseassertblog.get_url()=='/blog'# if you want to disable reversion, use the url argumentdjango=menu.Node(id='django',label='Django project',url='http://djangoproject.com',link_attrs={'target':'_blank'})# Each node instance can accept an arbitrary number of childrenblog.add(menu.Node(id='last_entries',label='Last entries',pattern_name='blog:last_entries'))blog.add(menu.Node(id='archives',label='Archives',pattern_name='blog:archives'))# will be shown to anonymous users onlylogin=menu.AnonymousNode(id='login',label='Login',pattern_name='accounts_login',link_attrs={'class':'big-button'})main_menu.register(login)# will be shown to authenticated users onlylogout=menu.AuthenticatedNode(id='logout',label='Logout',pattern_name='accounts_logout')main_menu.register(logout)

You can also directly set children nodes on parent instanciation with the children argument:

user=menu.Node(id='user',label='Greetings',pattern_name='user:dashboard',children=[menu.Node(id='logout',label='Logout',pattern_name='user:logout'),# you can nest children indefinitelymenu.Node(id='settings',label='Settings',pattern_name='user:settings',children=[menu.Node(id='newsletter',label='Newsletter',pattern_name='user:settings:newsletter')],),])

Nodes can be customized in many ways:

heavily_customized_node=menu.Node('customized','My custom menu',url='#',# a custom CSS class that will be applied to the node on renderingcss_class='custom-class',# the <a> title attributetitle='click me!',# a path to a custom template for rendering the nodetemplate='myapp/menu/mynode.html',# extra context you can use in your node templatecontext={'foo':'bar'},# a dict of attributes that will be applied as HTML attributes on the <li>attrs={'style':'background-color: white;'}# a dict of attributes that will be applied as HTML attributes on the <a>link_attrs={'target':'_blank','data-something':'fancy-stuff'})

Current node

You’ll probably want to highlight the current node in some way. Navutils provide
a view mixin you an inherit from in order to achieve this.

Under the hood, the mixin will pass the value to the context and a current class will be added

to the login node if the view is displayed. Note that you can achieve the same result
with django function-based views, as long as you manually pass the node identifier in the context,
under the current_menu_item key.