Skip to main content
siarp.de

## You are here

# Plone 3: How to really exclude from navigation

21. August 2009 - 0:49 — Martin

Plone has multiple ways of excluding a content object from the navigation:

- In the edit tab of the object under settings check "Exclude from navigation"
- Add the ID to `idsNotToList` in `portal_properties/navtree_properties`
- Add the meta type to `metaTypesNotToList` in `portal_properties/navtree_properties`

This works fine but the item is still displayed in the navigation tree if it's the current item (the one you're currently viewing). This may have a reason (usability?) but it is not what I want in some cases. If you put a link to the terms and conditions in the footer, for example, you don't want this to show up in the navigation tree when you click on it.

To solve this you can override the template for the navigation portlet (it may also work for the portal tabs) and add the conditions for the exclusion there.

## Overriding the navigation portlet template

Copy the files `navigation.pt` and `navigation_recurse.pt` to your package. Then create a file `navigation.py` with the following content to create your own renderer based the original overriding the templates:

from plone.app.portlets.portlets.navigation import Renderer
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
class MyRenderer(Renderer):
_template = ViewPageTemplateFile('navigation.pt')
recurse = ViewPageTemplateFile('navigation_recurse.pt')

Next, you have to register the class in the `configure.zcml` to override the original renderer.

<configure
xmlns:plone="http://namespaces.plone.org/plone">
<include package="plone.app.portlets" />
<plone:portletRenderer
portlet="plone.app.portlets.portlets.navigation.INavigationPortlet"
class=".navigation.MyRenderer"
/>
</configure>

(Note: If you want to do this for one theme only, put the code into your theme package and add `layer="..browser.interfaces.IThemeSpecific"` to the `<plone:portletRenderer>` element.)

If you restart Zope now, you are using your own class and templates but there's no difference, yet.

## Adding conditions to really exclude from navigation

First we expose the `idsNotToList` and `metaTypesNotToList` properties to the templates by adding the following to `navigation.py`:

...
from plone.memoize.instance import memoize
from Products.CMFCore.utils import getToolByName
class MyRenderer(Renderer):
...
@memoize
def getMetaTypesNotToList(self):
context = self.context
portal_properties = getToolByName(context, 'portal_properties')
navtree_properties = getattr(portal_properties, 'navtree_properties')
return list(navtree_properties.metaTypesNotToList)
@memoize
def getIdsNotToList(self):
context = self.context
portal_properties = getToolByName(context, 'portal_properties')
navtree_properties = getattr(portal_properties, 'navtree_properties')
return list(navtree_properties.idsNotToList)

Now we can finally add the conditions to the template so the item is not displayed in the navigation portlet any more. In `navigation_recurse.pt` change

tal:condition="python:bottomLevel &lt;= 0 or level &lt;= bottomLevel"

to

tal:condition="python:(not node['item'].id in view.getIdsNotToList()) and (node['portal_type'] not in view.getMetaTypesNotToList()) and (not node['item'].exclude_from_nav) and (bottomLevel &lt;= 0 or level &lt;= bottomLevel)"

That's it!

References:

- http://plone.org/documentation/how-to/override-the-portlets-in-plone-3.0/
- http://plone.org/support/region/de#nabble-td1643152%7Ca1643152

Attachment | Size
--- | ---
plonetutorial.excludefromnav-1.0dev-py2.4.egg | 5.84 KB
Bild 10.png | 169.72 KB
Bild 11.png | 169.42 KB
Bild 13.png | 146.64 KB