10.5.2. Navigation

Warning

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"));

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.

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"));

Note

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.

Node Visitor

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:

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">&nbsp;</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">&nbsp;</span>

returns false.

Filtering Navigation Nodes

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");
    }
});

Creating a Navigation Node

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);

Note

The node is not visible (or persisted) until saveNode is invoked.

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 both. The changes to the node visiblity is not shown until saveNode is invoked on the Portal.

Localization

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);

Deleting a Navigation 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);

Note

The node is not removed until saveNode is invoked.

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.

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);

Note

As with creating a node, the changes are not visible (or persisted) until saveNode is invoked.

Copyright ©. All rights reserved. eXo Platform SAS
blog comments powered byDisqus