#106: Using Five Views for Navigational Elements/Slots
- Contents
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
Use VHM rooting as the prime source of rooting. Example:
Accessing http://host/VirtualHostBase/http/math.foo.org:80/math/VirtualHostRoot/doc1/ would automatically root the navigation at '/math'.
Apply rooting to catalog searches too
Have a toggle to opt-out of automatic rooting.
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