A soft root is a page that acts as the root for a menu
navigation tree.
Typically, this will be a page that is the root of a significant
new section on your site.
When the soft root feature is enabled, the navigation menu
for any page will start at the nearest soft root, rather than
at the real root of the site’s page hierarchy.
This feature is useful when your site has deep page hierarchies
(and therefore multiple levels in its navigation trees). In such
a case, you usually don’t want to present site visitors with deep
menus of nested items.
For example, you’re on the page “Introduction to Bleeding”, so the menu might look like this:
The menu system isn’t monolithic. Rather, it is composed of numerous active parts, many of which can operate independently of each other.
What they operate on is a list of menu nodes, that gets passed around the menu system, until it emerges at the other end.
The main active parts of the menu system are menu generators and modifiers.
Some of these parts are supplied with the menus application. Some come from other applications (from the cms application in django CMS, for example, or some other application entirely).
All these active parts need to be registered within the menu system.
Then, when the time comes to build a menu, the system will ask all the registered menu generators and modifiers to get to work on it.
A modifier examines the nodes that have been assembled, and modifies them according to its requirements (adding or removing them, or manipulating their attributes, as it sees fit).
An important one in cms (cms.menu.SoftRootCutter) removes the nodes that are no longer required when a soft root is encountered.
later, by the template tag, with the argument post_cut=True
This corresponds to the state of the nodes list before and after menus.templatetags.menu_tags.cut_levels(), which removes nodes from the menu according to the arguments provided by the template tag.
This is because some modification might be required on all nodes, and some might only be required on the subset of nodes left after cutting.
A NavigationNode has attributes such as URL, title, parent and children - as one would expect in a navigation tree.
It also has an attr attribute, a dictionary that’s provided for you to add arbitrary attributes
to, rather than placing them directly on the node itself, where they might clash with something.
Warning
You can’t assume that a menus.base.NavigationNode represents a django CMS Page. Firstly, some nodes may
represent objects from other applications. Secondly, you can’t expect to be able to access Page objects via
NavigationNodes. To check if node represents a CMS Page, check for is_page in menus.base.NavigationNode.attr
and that it is True.
Let’s look at an example using the {%show_menu%} template tag. It will be different for other
template tags, and your applications might have their own menu classes. But this should help
explain what’s going on and what the menu system is doing.
One thing to understand is that the system passes around a list of nodes, doing various things
to it.
Many of the methods below pass this list of nodes to the ones it calls, and return them to the ones
that they were in turn called by.