#106: Using Five Views for Navigational Elements/Slots

Contents
  1. Motivation
  2. Proposal
  3. Implementation
by Sidnei da Silva last modified Jan 21, 2010 07:25 AM

This proposal aims to define the interfaces (in the Zope 3 sense) that the navigation-related views should provide.

Proposed by
Sidnei da Silva
Proposal type
Architecture
Assigned to release
State
completed

Motivation

Too much logic can be found on the templates that provide navigational elements in the Plone UI.

Customizing simple stuff like:

  • What objects show/don't on the navigation tree and breadcrumbs
  • Using a different/shorter label (default is Title) for navigation tree and breadcrumbs
  • Deciding if an item is selected or not in the navigation tree/breadcrumb
  • Deciding or not to expand a node in the navigation tree

Proposal

  • Moving all the logic from templates and helper scripts into View classes that can be tested.
  • Moving policy decisions (what attribute to use as title, when to show or not an item in navigation/breadcrumbs) to Adapters.

Alternate/Additional Proposal

Implementation

Navigation Tree

Currently hardcoded to a script named portlet_navtree_macro. This would be replaced by a view named navigation_tree on the currently viewed object.

Before:

<li tal:replace="structure python:here.portlet_navtree_macro(children=data.get('children', []), level=1, show_children=True, isNaviTree=True)">
    SUBTREE
</li>

After:

<li tal:replace="structure context/@@navigation_tree">
    SUBTREE
</li>

This will allow anyone to override the navigation for a given object, and even for the whole site by simply registering a view with the same name.

In early stages this will be all handled by ZCML directives. Later on, a local version of the 'Presentation Service' will be provided so customizations can be done on a per-site basis, akin to portal_skins.

As the view is rendered by using tal:replace="structure", the view can do whatever it chooses to. It could use Page Templates, Python or XSLT, as long as it returns HTML.

The default navigation_tree view would work pretty much the same way as the existing one does right now. In fact, for a start it could even just call the current portlet_navtree_macro script like it's done now.

A proposal for a new Navigation Tree using Five Views, Interfaces and Adapters can be found on PLIP #107 Five-enhanced Navigation Tree.

Breadcrumbs

Here, the use of Views would also simplify a lot the logic behind building breadcrumbs. Currently, this is hardcoded in the method createBreadCrumbs in the plone_utils tool, effectively making customization impossible without replacing the whole plone_utils tool by a custom version or monkey patching the method.

The proposed solution is to use a breadcrumbs view, that could be accessed by context/@@breadcrumbs.

The default implementation of this view then could behave pretty much like it's done in Zope 3, by returning querying the container's breadcrumbs view and appending the information about the current node to that.

(In Zope 3, breadcrumbs is actually a method of the IAbsoluteURL View)

Sample Code:

...
def breadcrumbs(self):
    context = self.context
    request = self.request

    container = aq_parent(context)
    if container is None or not ITraversable.providedBy(container):
        bc = ({'name': context.getId(),
                 'url': context.absolute_url()
                 },)
    else:
        view = getViewProviding(container, IAbsoluteURL, request)
        bc = tuple(view.breadcrumbs())
        name = context.getId()
        bc += ({'name': name,
                  'url': ("%s/%s" % (base[-1]['url'], name))
                  },)
   return bc
...

Slots/Portlets

Left/Right slots (a.k.a. portlets) are looked up by the script prepare_slots. By default it looks for an attribute of the object (including acquisition) and checks if the value is callable.

While the whole thing looks rather reasonable, the use of an extra attribute on the object itself and possible acquisition make it hard to discover, and mix content and presentation.

Here, again, the use of a View, say context/@@slots would help by abstracting the presentation-dependent aspect which is the list of slots to display out of the content object into a presentation-specific component.

Again, a default View could be provided that still looks up the values in attributes/acquisition to keep backwards compatibility, while allowing for greater customization without having to touch content-space for changing the slots to bee displayed.

link broken

Posted by Adam Theo at Jun 17, 2006 09:16 PM
the link to plip 107 is broken. the URL should be 'http', not 'https'.