NavTool - Documentation topics on: crumbtrail,menus,navigation,navtool,reorder menu,sitemap,site map,.

NavTool

The $navtool Velocity viewtool allows you to create custom navigations with your own HTML and styles. It builds a navigation structure given a path or folder level, and returns a list of navigation items.

Usage

You can use the NavTool through both methods and properties, all of which return an object representing a folder in the dotCMS folder tree.

Methods

The getNav() method allows you to access the current folder or to pass in different parameters to access a folder on your site via an absolute path or a relative folder level.

MethodReturn ValueDescription
$navtool.getNav()Nav objectCurrent Folder
Returns the current active navigation folder (the folder where the current page is located).
$navtool.getNav( path )Nav objectAbsolute Path
Returns the children in the specified folder.
$navtool.getNav( level )Nav objectRelative Folder Level
Returns the children of the folder at the specified folder level within the path of the page where the method call is made.

Parameters

The getNav() method accepts either a string (a folder path) or an integer (a folder level) as an argument. Both arguments are referenced from the root of the site where the page is located.

ParameterTypeDescription
pathStringThe folder path to the root of the navigation tree to be displayed.
levelIntegerThe folder level to display within the path to the current page.
0 specifies the root folder of the Site the page is located on, 1 specifies the top-level folder in the current page's path, 2 specifies the next lower level folder in the current page's path, etc.

Method Examples

The following examples describe which folder is returned for different calls to $navtool.getNav() if the method call is made from the “/about-us/locations/index” page on the dotCMS starter site or dotCMS demo site.

MethodReturned Nav Object
$navtool.getNav()The “/about-us/locations” folder (the folder where the page is located).
$navtool.getNav( "/" )The root folder of the site the page is displayed on.
$navtool.getNav( "/application" )The “/application” folder on the site the page is displayed on.
$navtool.getNav( "//demo.dotcms.com/application" )The “/application” folder on the demo.dotcms.com site.
Note: This only works if demo.dotcms.com is a host on the same dotCMS instance as the page where the code is run.
$navtool.getNav( 0 )The root folder of the site the page is displayed on.
(Equivalent to $navtool.getNav("/").
$navtool.getNav( 1 )The “/about-us” folder.
(Equivalent to $navtool.getNav("/about-us")).
$navtool.getNav( 2 )The “/about-us/locations” folder.
(Equivalent to $navtool.getNav("/about-us/locations")).

Properties

If you specify the $navtool object directly, it returns the nav object of the current active folder (where the page is located). This is equivalent to calling $navtool.getNav() (with no arguments).

You may specify the properties of the $navtool object directly (without first having to assign the results to a Velocity variable), and you may chain the properties. This allows you to easily access nav objects for folders relative to the current folder with a single Velocity reference.

Property Examples

The following examples describe which folder is returned for different NavTool property references if the reference is made from the “/about-us/locations/index” page on the dotCMS starter site or dotCMS demo site.

ReferenceReturned Nav Object
$navtoolThe “/about-us/locations” folder (the folder where the page is located).
$navtool.parentThe “/about-us” folder (the parent of the folder where the page is located).
$navtool.parent.parentThe root folder of the site.
$navtool.childrenA list of all siblings of the current page (all objects (files, pages and folders) in the “/about-us/locations” folder).
$navtool.parent.childrenA list of all siblings of the current folder (all objects (files, pages and folders) in the “/about-us” folder).

Return Values

The navtool methods and properties each return a nav object, which contains the following properties:

PropertyTypeDescription
parentNav objectParent folder.
childrenList of Nav objectsList of children (if the content item is a folder).
titleStringTitle of the content item.
hrefStringURL (href) of the content item.
Clicking this link navigates to the page or file.
orderIntSort Order field of the content item.
activeBooleanTrue if the content item is active.
folderBooleanTrue if the content item is a folder.
typeStringType of content item (“folder”, “htmlpage”, “link”, or “file”).
codeLinkStringCode Link field value (only if the content item is a Menu Link with a Code Link value set).

For example, if you access the nav object using #set($navobj = $navtool.getNav("/")), then you would reference the title parameter as $navobj.title.

Navigation Permissions

By default, the NavTool does not check permissions. This means users will see all navigation items, even if they don't have permission to view those items.

To configure the NavTool to respect permissions, change the ENABLE_NAV_PERMISSION property to true in the dotmarketing-config.properties file. After this change, only items the current user has permissions to View are returned in the navigation.

ENABLE_NAV_PERMISSION_CHECK=true

Note:

  • It is strongly recommended that any changes to the dotmarketing-config.properties file be made through a configuration file extension.
  • If the ENABLE_NAV_PERMISSION_CHECK property is enabled, it is recommend that you enclose the navigation in a #dotcache block to avoid performance degradation.

Examples

The following examples demonstrate several different ways to use the navigation tool to display navigation objects and customize navigation.

Example: Get the Current Active Navigation Folder

You can get the current active navigation folder by calling navtool.getNav() without any arguments.

#set($nav = $navtool.getNav())

Example: Two level Navigation

This example displays the navigation from the root of the folder tree, highlighting the active folder with the <strong> tag (if close enough to the root folder to be displayed in the navigation). The dotCMS documentation site left-side navigation bar uses a method similar to this to display the documentation tree.

#set( $list = $navtool.getNav("/") )
<ul>
  #foreach($n in $list)
    <li>
      <a href='${n.href}'>${n.title}</a>
      #set($children = $n.children)
      #if( $children && $children.size() > 0 )
        <ul>
          #foreach($child in $children)
            <li>
              #if($child.active)<strong>#end <a href='${child.href}'>${child.title}</a> #if($child.active)</strong>#end
              #set($grandchildren = $child.children)
              #if( $grandchildren && $grandchildren.size() > 0 )
                <ul>
                  #foreach($grandchild in $grandchildren)
                    <li>#if($grandchild.active)<strong>#end <a href='${grandchild.href}'>${grandchild.title}</a> #if($grandchild.active)</strong>#end
                  #end
                </ul>
              #end
            </li>
          #end
        </ul>
      #end
    </li>
  #end
</ul>

Example: Display the Navigation for the Parent Folder

This example works almost exactly the same as the previous example, but instead of displaying the navigation from the root of the folder tree, this example displays the navigation from 1 level up from the current folder (the parent folder), displaying both the current folder's siblings and children. As with the previous example, the active folder will be highlighted with the <strong> tag.

#set( $list = $navtool.getNav(1) )
<ul>
  #foreach($n in $list)
    <li>
      <a href='${n.href}'>${n.title}</a>
      #set($siblings = $n.children)
      #if( $siblings && $siblings.size() > 0 )
        <ul>
          #foreach($sib in $siblings)
            <li>
              #if($sib.active)<strong>#end <a href='${sib.href}'>${sib.title}</a> #if($sib.active)</strong>#end
              #set($children = $sib.children)
              #if( $children && $children.size() > 0 )
                <ul>
                  #foreach($child in $children)
                    <li><a href='${child.href}'>${child.title}</a>
                  #end
                </ul>
              #end
            </li>
          #end
        </ul>
      #end
    </li>
  #end
</ul>

Example: Add a “Reorder” button in Edit Mode

The following code adds a re-order button to the custom navigation when the page is viewed in Edit mode. For a more complete example using this method, see the Custom Navigation example, below.

#if ($EDIT_MODE)
   #set($PUBLISH_PERMISSION = $pageAPI.canUserPublish($HTMLPAGE_IDENTIFIER, false))
   #set($startFromPath = "/")
   #set($folder = $folderAPI.findCurrentFolder($startFromPath, $host))
   #set($menuId = $folder.inode)
   #set($count = 1)
   <form action="${directorURL}" method="post" name="dot_form_menu_${count}" id="dot_form_menu_${count}">
     <input type="hidden" name="cmd" value="orderMenu" />
     <input type="hidden" name="path" value="$startFromPath" />
     <input type="hidden" name="hostId" value="${host.identifier}" />
     <input type="hidden" name="pagePath" value="${VTLSERVLET_URI}" />
     <input type="hidden" name="referer" value="${VTLSERVLET_URI}" />
     <input type="hidden" name="startLevel" value="1" />
     <input type="hidden" name="depth" value="2" />
     #if ($PUBLISH_PERMISSION)
       <div class="dotMenuReorder"><a href="javascript:document.getElementById('dot_form_menu_${count}').submit();"></a></div>
     #else
       <div class="dotMenuReorder"></div>
     #end

   </form>
   #set($count = $math.add($count, 1))
#end

Example: Build a Crumbtrail

The following code builds a crumbtrail up to 25 levels deep (based on the Show on Menu settings on the pages, files and folders in your site).

## Get the Nav item for the current folder
#set($current = $navtool.getNav())

## Build the list of folders to display in the crumbtrail
#set($crumb = $contents.getEmptyList())
#set($_x=$crumb.add(0,$current))
#foreach($item in [1..25])
     #set($current = $current.parent)
     #if($current.title=="System folder")
          #break
     #end
     #set($_x=$crumb.add(0,$current))
#end

## Display the crumbtrail
<ul>
     <li style="display:inline"><a href="/">Home</a></li>
     #foreach($item in $crumb)
          <li style="display:inline">     
               <a href="$item.href">$item.title</a>
          </li>
     #end
</ul>

Example: Custom Navigation

The following code uses the Navigation Tool to create a full custom navigation scheme.

#macro(navToolSubmenu $nav_children $num)
  #set($num = $num+1)
  <ul>
    #foreach($nav_item in $nav_children)
      #if(!$nav_item.href.contains("index.dot"))
        #if($UtilMethods.isSet($nav_item.codeLink))
          <li>$nav_item.codeLink</li>
        #else
          #if($UtilMethods.isSet($nav_item.href))
            <li#if($nav_item.active == true) class="active"#end>
              <a href="${nav_item.href}">$nav_item.title</a>
              #if(($nav_item.active == true || $open_levels == true) && ($nav_item.children && $nav_item.children.size() > 0 && $levels_deep > 1))
                #navToolSubmenu($nav_item.children)
              #end
            </li>
          #end
        #end
      #end
    #end
  </ul>
#end

#macro(navTool $main_sub, $levels_deep, $open_levels)

  ## DEFAULT IS SET TO Root
  #if(($UtilMethods.isSet($main_sub) && $main_sub == 1) || ($UtilMethods.isSet($main_sub) && $main_sub == "") || !$UtilMethods.isSet($main_sub))
    #set($main_sub = "main")
  #else
    #set($main_sub = "$main_sub")
  #end

  ## DEFAULT IS SET TO 1 LEVEL DEEP
  #if((!$UtilMethods.isSet($levels_deep)) || ($UtilMethods.isSet($levels_deep) && $levels_deep == "") || ($UtilMethods.isSet($levels_deep) && $levels_deep == 0))
    #set($levels_deep = 1)
  #elseif($UtilMethods.isSet($levels_deep) && $levels_deep > 5)
    #set($levels_deep = 5)
  #end

  ## SET IF ALL SUB FOLDER AND PAGES SHOULD SHOW ON EVERY PAGE
  ## IF SET TO TRUE, ONLY SHOWS SUB FOLDERS AND PAGES WITHIN A CHILD DIRECTORY
  ## DEFAULT IS FALSE
  #if(!$UtilMethods.isSet($open_levels))
    #set($open_levels = false)
  #elseif($UtilMethods.isSet($open_levels))
    #if($open_levels == "true")
      #set($open_levels = true)
    #elseif($open_levels == "false" || $open_levels == "")
      #set($open_levels = false)
    #end
  #end

  #if($main_sub == "main")
    ##GET NAVIGATION LIST, START AT ROOT
    #set($nav_list = $navtool.getNav("/"))
  #elseif($main_sub == "sub")
    ##GET NAVIGATION LIST, START AT LOCAL PARENT DIRECTORY
    #set($nav_current_parent = $VTLSERVLET_URI.split('/').get(1))
    #set($nav_list = $navtool.getNav("/${nav_current_parent}"))
  #else
    ##GET NAVIGATION LIST, START AT ROOT
    #set($nav_list = $navtool.getNav("$main_sub"))
  #end

  <!-- New Navigation Macro navTool - v1 -->
  <ul>
    #foreach($nav_item in $nav_list)
    <li id="$nav_item.href.replace("/","")" #if($nav_item.active == true)class="active"#end>
      <a href="$nav_item.href">$!{nav_item.title}</a>
      ##IF LINK HAS CHILDREN
      #if(($nav_item.active == true || $open_levels == true) && ($nav_item.children && $nav_item.children.size() > 0 && $levels_deep > 1))
        #navToolSubmenu($nav_item.children 2)
      #end
    </li>
    #end
  </ul>

  ##*******  REORDER IN EDIT MODE *******##
  #if($EDIT_MODE)
    #set($PUBLISH_PERMISSION = $pageAPI.canUserPublish($HTMLPAGE_IDENTIFIER, false))
    #set($startFromPath = "/")
    #set($folder = $folderAPI.findCurrentFolder($startFromPath, $host))
    #set($menuId = $folder.inode)
    #set($count = 1)
    <form action="${directorURL}" method="post" name="dot_form_menu_${count}" id="dot_form_menu_${count}">
      <input type="hidden" name="cmd" value="orderMenu" />
      <input type="hidden" name="path" value="$startFromPath" />
      <input type="hidden" name="hostId" value="${host.identifier}" />
      <input type="hidden" name="pagePath" value="${VTLSERVLET_URI}" />
      <input type="hidden" name="referer" value="${VTLSERVLET_URI}" />
      <input type="hidden" name="startLevel" value="1" />
      <input type="hidden" name="depth" value="2" />
      #if ($PUBLISH_PERMISSION)
        <div class="dotMenuReorder"><a href="javascript:document.getElementById('dot_form_menu_${count}').submit();"></a></div>
      #else
        <div class="dotMenuReorder"></div>
      #end
    </form>
  #set($count = $math.add($count, 1))
  #end

#end

Toolbox.xml Configuration

The NavTool is enabled by default in dotCMS. To ensure the NavTool is enabled, verify that the following lines exist in your toolbox.xml file:

<tool>
    <key>nav</key>
    <scope>request</scope>
    <class>com.dotmarketing.viewtools.NavigationWebAPI</class>
</tool>

References

For complete documentation on this viewtool, please see the following documentation: