customizing the navigation portlet in Plone 3

by Guido Stevens last modified Aug 13, 2009 07:33 AM
how to customize the navigation portlet in a few easy steps

Purpose

Once upon a time customization of the Plone navigation portlet was easy. You just dropped a customized portlet_navigation.pt into a (custom) skins layer and presto.

In Plone3, customizing the navigation is still very easy. But it requires a bit more understanding of the component architecture.

Prerequisities

  • A Plone 3 installation.
  • A theme product that contains your customizations.

Step by step


1. Find the source of the default navigation portlet implementation.

The navigation portlet is provided by plone.app.portlets

.

In a buildout-based installation, goto: eggs/plone.app.portlets-1.1.3-py2.4.egg/plone/app/portlets/portlets or something like that with a different version number. Alternatively, on Linux, you can do a locate navigation_recurse.pt

to find the relevant directory.

The relevant files are:
navigation.py
the python module that powers the navigation portlet
navigation.pt
the wrapper template for portlet border, header and footer
navigation_recurse.pt
the renderer for the actual navigation tree 

2. Copy the TAL templates to your theme

Copy the navigation templates from plone.app.portlets into your theme's browser/templates directory.

In a buildout-based installation, with your custom theme product "my.theme", the command is:

cp eggs/plone.app.portlets-1.1.3-py2.4.egg/plone/app/portlets/portlets/navigation*pt src/my.theme/my/theme/browser/templates/

Don't copy navigation.py!

3. Subclass the portlet Renderer

In your theme's browser directory, create your own navigation.py. It needs only the following measly five lines of code:

from plone.app.portlets.portlets.navigation import Renderer

from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile

class MyNavRenderer(Renderer):
    
     _template = ViewPageTemplateFile('templates/navigation.pt')
     recurse = ViewPageTemplateFile('templates/navigation_recurse.pt')

4. Activate your customizations in configure.zcml

In your my.theme/my/theme/browser/configure.zcml

put the following lines:

<!-- Customize the navigation portlet -->
       <plone:portletRenderer
       portlet="plone.app.portlets.portlets.navigation.INavigationPortlet"
       layer=".interfaces.IThemeSpecific"
       class=".navigation.MyNavRenderer"
       />

Make sure you've got this line in the header of your configure.zcml:

<configure
    ...whatever is there already...
    xmlns:plone="http://namespaces.plone.org/plone"
>

Restart your Zope instance for this change to take effect.

5. Customize the navigation templates

You can now customize both the outer navigation.pt and the recursing navigation_recurse.pt TAL templates in your theme's browser/templates as you wish.

Further information

A more elaborate version of this HOWTO is available on transcyberia.info. The article over there provides extra background information and a schematic of the call flow involved in rendering the navigation portlet.

Change history

  • Fixed target directory for templates to browser/templates (Thanks to Samuel Wong)
  • documented xmlns:plone dependency (Thanks to Ben Eveling)