#107: Five-enhanced Navigation Tree
- Contents
- Proposed by
- Sidnei da Silva
- Proposal type
- User interface, Architecture
- State
- rejected
Motivation
The Navigation Tree shipped with Plone 2.1 has several features, controlled by properties in the portal_properties tool and some extra parameters. However, that is not fine-grained enough to cover most of the cases. In fact, very few people are brave enough to customize the default Navigation Tree because doing so requires deep knowledge of how the Navigation Tree is built, and may even require modifying/patching existing source.
Proposal
In the light of PLIP #105 Using Five/Zope 3 Views, we would like to propose the use of Views, Interfaces and Adapters to introduce simple extension/customization points while providing a powerful default Navigation Tree.
People customizing small pieces of behaviour will be presented with a simpler and familiar way of changing this behaviour, without requiring full knowledge of the internals of the Navigation Tree.
People that want to replace the Navigation Tree as a whole can do so by providing a custom view that can use whatever other technology suits best their needs, as described on PLIP #106 Using Five Views for Navigational Elements/Slots.
Implementation
Instead of using random properties, and lists/blacklists of portal type to show/hide from the Navigation Tree, we will use marker interfaces. Those interfaces should live inside Plone.
The proposed interfaces are:
- INavigationInclude
- INavigationExclude
- INavigationForceExclude
- INavigationLeaf
Content that by default should be included/excluded from navigation should declare to implement one or more of those interfaces according to the desired semantics.
At runtime, a user will be able to add and remove marker interfaces to modify the behaviour on a per-object basis by using the UI provided by PLIP #104 Moving Flon into Plone core
Enfold Systems can provide existing code with tests that implements all of the listed use-cases. This code uses NavtreeIndexNG and MenuGenerator to do it's job and it's quite fast, but a more customized index could possibly provide a even faster implementation.
Several use-cases are covered by the implementation, and tests for all of them exist:
- Objects which do not declare to provide INavigationInclude or do provide INavigationExclude are not included in the Navigation Tree
- If the entry path matches the start of the current path:
- If it's a exact match, the initial entry state is set to 'Selected'.
- If it's a substring match from the start of the path, the initial entry state is set to 'Selected-Children'
- Otherwise, the initial entry state is set to 'Normal'
- If the entry provides INavigationForceExclude, the entry is skipped. If the entry state was set to 'Selected', the parent node is changed from 'Selected-Children' to 'Selected'.
- If the current state is 'Selected' and the entry does not provide
INavigationInclude:
- If the entry is not 'folderish' and provides INavigationExclude it should never show up in the Navigation Tree.
- If the entry provides INavigationLeaf:
- A 'leaf' flag is added to the current node.
- If the current entry state is not 'Selected-Children' we stop recursion.
- If the entry's parent node has the 'leaf' flag, only include the current entry if in the 'Selected' or 'Selected-Children' state.
We do believe those cases cover a great deal of the possible use cases for a Navigation Tree, and as they have proper tests coverage it can be expanded to cover yet more cases without breaking proper backward compatibility.
The code is currently being used and can be seen in action at Oxfam America.