Chapter 5. Navigation
5.1. Retrieving Navigation Nodes
When retrieving navigation nodes it is possible to either retrieve the root node, or a specific node in the hierarchy. It is also possible to control which if any of the children are loaded.
Example 5.1. Basic Navigation Portlet
This example shows a very simple navigation portlet that displays the top level of entries in the navigation menu.
public void doView(RenderRequest request, RenderResponse response) throws IOException { PrintWriter pw = response.getWriter(); Navigation navigation = PortalRequest.getInstance().getNavigation(); pw.print("<ul>"); for (Node n : navigation.getRootNode(Nodes.visitChildren())) { pw.printf("<li><a href='%s'>%s</a></li>", n.getURI(), n.getDisplayName()); } pw.print("</ul>"); }
Example 5.2. Retrieve a Specific Node
This example demonstrates how to retrieve a specific node in the tree by specifying the
NodePath to the node.
Node node = navigation.getNode(NodePath.path("home"));
Note
When a node is retrieved, it actually represents a tree of nodes and all operations (for example, save and refresh) act on that entire tree. For example, if a root node with two child nodes is retrieved, and changes are made to the both child nodes but only one node is saved, the other child will be saved automatically because the save operation acts on the entire node tree.
5.1.1. NodeVisitor
It is important to limit how many levels of navigation nodes are retrieved, especially where there is a large number of nodes. This is controlled by using either one of the built in
NodeVisitor from the Nodes class, or by implementing your own NodeVisitor . The Nodes class contains the following visitors:
- visitAll - loads all nodes
- visitChildren - loads the immediate children
- visitNone - loads only the node
- visitNodes(int) - loads a specified depth of descendants
Example 5.3. Retrieve a Node Using visitNodes
This example retrieves the root node and two levels of nodes.
Node rootNode = navigation.getRootNode(Nodes.visitNodes(2));
Example 5.4. isChildrenLoaded versus visitChildren Method
To correctly confirm whether the child nodes are loaded, use the
isChildrenLoaded method instead of visitChildren.
This would return true:
Node rootNode = navigation.getRootNode(Nodes.visitChildren()).isChildrenLoaded()
This would return false:
Node rootNode = navigation.getRootNode(Nodes.visitNone()).isChildrenLoaded()
5.1.2. Filtering Navigation Nodes
Nodes support a filtering mechanism which simplifies displaying nodes that have specific properties.
Example 5.5. Display User-visible Nodes When Creating a Navigation Portlet
This example displays visible nodes where the user has access to view the page.
Node filtered = node.filter().showDefault();
There are a number of methods available to control what nodes are displayed, and they all start with
show . For example, showDefault is an abbreviation for showVisible().showHasAccess(PortalRequest.getInstance().getUser())
Example 5.6. Custom Filter
This example uses a custom filter to only display nodes with a display name that starts with "A".
Node filtered = root.filter().show(new Filter<Node>() { public boolean accept(Node node) { return node.getDisplayName().startsWith("A"); } });
5.2. Creating a Navigation Node
Creating a node uses the following workflow:
- Retrieve the parent node you want to add the node to.
- Invoke the
addChildmethod on the parent node. - Set the configuration for the node (such as the display name and the page it should link to).
- Save it using
saveNodeonNavigation.
Example 5.7. Creating a Navigation Node
This example creates a node as a child of the home node.
The node is not visible (or persisted) until
saveNode is invoked.
Node home = navigation.getNode(NodePath.path("home")); Node child = home.addChild("mynode"); child.setDisplayName("My Node"); child.setPageId(new PageId("classic", "mypage")); navigation.saveNode(home);
5.2.1. Navigation Node Visibility
Nodes can be visible, hidden or only visible at a specified publication date. By default a new node is visible.
A node can be hidden with
node.setVisibility(false), or only shown until a specific date with node.setVisibility(PublicationDate.endingOn(date)). It is also possible to set a starting date, or set both a starting date and a finishing date.
Changes to node visibility are not shown until
saveNode is invoked on the Portal.
5.2.2. Localization
The display name for a node supports localization.
Example 5.8. Setting and English and French Node
This example sets the display name for a node in English and French.
LocalizedString localizedString = node.getDisplayNames(); localizedString.setLocalizedValue(Locale.ENGLISH, "My node"); localizedString.setLocalizedValue(Locale.FRENCH, "Mon noeud"); node.setDisplayNames(localizedString); navigation.saveNode(node);
5.3. Deleting a Navigation Node
A node is deleted by removing it from the parent node.
Example 5.9. Deleting a Node
This example removes the child with the name mynode.
The node is not removed until
saveNode is invoked.
node.removeChild("mynode"); navigation.saveNode(node);
5.4. Moving a Navigation Node
A node can be moved to a different parent, or it can be moved to a different index in the same parent. When moving to a different parent the new parent is required to be in the same tree.
Example 5.10. Move Child Nodes Between Parent and Index Nodes
Move a node from one parent to another.
root.getNode("parent1", "child").moveTo(root.getNode("parent2")); navigation.saveNode(root);
Move a node to a different index in the same parent.
root.getNode("parent", "child").moveTo(0); navigation.saveNode(root);
The changes are not visible (or persisted) until
saveNode is invoked.
A more convenient way to sort children for a parent is to use the
sort method on the parent.
Example 5.11. Sorting by Display Name
This example demonstrates how to sort the children of the root node by their display names.
The changes are not visible (or persisted) until
saveNode is invoked.
root.sort(new Comparator<Node>() { public int compare(Node o1, Node o2) { return o1.getDisplayName().compareTo(o2.getDisplayName()); } }); navigation.saveNode(root);