You are looking at documentation for an older release. Not what you want? See the current release documentation.
A Navigation for a site is retrieved from the Portal and allows accessing the node tree that represents the navigation entries for the site. There is a special root node which is not directly part of the navigation, but it's the parent of the first level of navigation entries. As the root node is not meant to be displayed it doesn't have a display name.
The example below retrieves the Navigation for the classic site:
Navigation navigation = portal.getNavigation(new SiteId("classic"));
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.
This example below 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>");
}
To retrieve a specific node in the tree it's retrieved by specifying the NodePath to the node:
Node node = navigation.getNode(NodePath.path("home"));
It is important to note that when you retrieve a node, it actually represents a tree of nodes and all operations (i.e. save, refresh) act on that entire tree. So if you retrieve the root node and it's children and make modifications to two children but only perform a save on one child, the other child will be saved since the save operation acts on the entire node tree.
When retrieving navigation nodes, especially if there is a large number of nodes it is important to limit how many levels of nodes are retrieved. 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.
The example below retrieves the root node and 2 levels of nodes:
Node rootNode = navigation.getRootNode(Nodes.visitNodes(2));
To find out if the children for a node is loaded use the isChildrenLoaded method. For example
<!-- <br/> --><span class="java_plain">navigation</span><!-- <br/> --><span class="java_separator">.</span><!-- <br/> --><span class="java_plain">getRootNode</span><!-- <br/> --><span class="java_separator">(</span><!-- <br/> --><span class="java_type">Nodes</span><!-- <br/> --><span class="java_separator">.</span><!-- <br/> --><span class="java_plain">visitChildren</span><!-- <br/> --><span class="java_separator">()).</span><!-- <br/> --><span class="java_plain">isChildrenLoaded</span><!-- <br/> --><span class="java_separator">()</span><!-- <br/> --><span class="java_plain"> </span>
returns true while
<!-- <br/> --><span class="java_plain">navigation</span><!-- <br/> --><span class="java_separator">.</span><!-- <br/> --><span class="java_plain">getRootNode</span><!-- <br/> --><span class="java_separator">(</span><!-- <br/> --><span class="java_type">Nodes</span><!-- <br/> --><span class="java_separator">.</span><!-- <br/> --><span class="java_plain">visitNone</span><!-- <br/> --><span class="java_separator">()).</span><!-- <br/> --><span class="java_plain">isChildrenLoaded</span><!-- <br/> --><span class="java_separator">()</span><!-- <br/> --><span class="java_plain"> </span>
returns false.
Nodes support a filtering mechanism which makes it simple to display only nodes that have certain properties. For example when creating a navigation portlet it is common to only want to display visible nodes where the user has access to view the page:
Node filtered = node.filter().showDefault();
There is a number of methods available to control what nodes are displayed, and they all start with show. showDefault is a short-cut for
</span> <!-- --><br/><span class="java_plain">showVisible</span><span class="java_separator">().</span><span class="java_plain">showHasAccess</span><span class="java_separator">(</span><span class="java_type">PortalRequest</span><span class="java_separator">.</span><span class="java_plain">getInstance</span><span class="java_separator">().</span><span class="java_plain">getUser</span><span class="java_separator">()).</span>
It is also possible to add a custom filter. The example below displays uses a custom filter to only 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");
}
});
To create a node, first retrieve the parent node you want to add it to, and invoke the addChild method on the parent node. Then set the configuration for the node (such as the display name and the page it should link to) and finally save it using saveNode on Navigation.
The example below creates a node as a child of the home node:
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);
The node is not visible (or persisted) until saveNode is invoked.
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 both. The changes to the node visiblity is not shown until saveNode is invoked on the Portal.
The display name for a node supports localization. The example below 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);
A node is deleted by removing it from the parent node. The example below removes the child with the name mynode:
node.removeChild("mynode");
navigation.saveNode(node);
The node is not removed until saveNode is invoked.
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.
The example belows moves a node from one parent to another:
root.getNode("parent1", "child").moveTo(root.getNode("parent2"));
navigation.saveNode(root);
Or to move a node to a different index in the same parent:
root.getNode("parent", "child").moveTo(0);
navigation.saveNode(root);
A more convinient way to sort children for a parent is to use the sort method on the parent, for example to sort the children of the root node by their display names:
root.sort(new Comparator<Node>() {
public int compare(Node o1, Node o2) {
return o1.getDisplayName().compareTo(o2.getDisplayName());
}
});
navigation.saveNode(root);
As with creating a node, the changes are not visible (or persisted) until saveNode is invoked.