Megrok.navigation lets you easily add all sorts of menus to a site.
Menus are implemented as viewletmanagers, and items as viewlets.
You can also override the default templates by registering your own IPageTemplate
>>> import grok
>>> class MySite(grok.Container, grok.Application):
... pass
>>> grok_component('mysite', MySite)
True
>>> root = getRootFolder()
>>> root['site'] = site = MySite()
>>> from zope.security.testing import Principal, Participation
>>> from zope.security.management import newInteraction, endInteraction
>>> participation = Participation(Principal('zope.anybody'))
>>> from zope.publisher.browser import TestRequest
>>> request = TestRequest()
>>> newInteraction(participation)
>>> nav = Navigation(site, request, grok.View(site, request))
>>> nav.update()
>>> len(nav.viewlets)
0
>>> print nav.render()
<ul class="">
</ul>
megrok.navigation uses zope.pagetemplate (or megrok.pagetemplate) to allow you to override the default templates.
Let’s define a template based on divs, instead of ul
>>> mt = """<div tal:attributes='class viewletmanager/cssClass'>
... <tal:repeat tal:repeat='viewlet viewletmanager/viewlets'
... tal:replace='structure viewlet/render'/>
... </div>"""
>>> from megrok import pagetemplate
>>> class DivMenu(pagetemplate.PageTemplate):
... template = grok.PageTemplate(mt)
... pagetemplate.view(navigation.interfaces.IMenu)
>>> grok_component('divmenu', DivMenu)
True
>>> it = """<div tal:attributes='class viewletmanager/cssItemClass'>
... <a tal:attributes="href viewlet/link;
... title viewlet/description|nothing">
... <img tal:condition="viewlet/icon | nothing"
... tal:attributes="src viewlet/icon"/>
... <span tal:replace="viewlet/title"/></a>
... <tal:replace tal:condition="viewlet/subMenu | nothing"
... tal:replace="structure provider:${viewlet/subMenu}"/>
... </div>"""
>>> class DivMenuItem(pagetemplate.PageTemplate):
... template = grok.PageTemplate(it)
... pagetemplate.view(navigation.interfaces.IMenuItem)
>>> grok_component('divmenuitem', DivMenuItem)
True
>>> print actions.render()
<div class="">
<div class="">
<a href="http://127.0.0.1/site/foo/fooindex">
<BLANKLINE>
Details</a>
<BLANKLINE>
</div>
<div class="">
<a href="http://127.0.0.1/site/foo/fooedit">
<BLANKLINE>
Edit</a>
<BLANKLINE>
</div>
<div class="">
<a href="http://127.0.0.1/site/foo/fooprotected">
<BLANKLINE>
Manage</a>
<BLANKLINE>
</div>
</div>