Wiki

This page is about the Confluence Wiki behind this site.

Left Navigation Tree

The navigation tree on the left is built using the same functionality as pages tree view. It uses AJAX style retrieval to display opened nodes without page refreshes.

This first chunk should be placed near the top of the Page Layout template. It includes styles to override the ones used in the page tree view. It also includes a macro that is used to generate the tree nodes. The nodes are by default generated to a depth of 3, but that can be changed here. Finally, it includes the necessary JavaScript functions to download and display new nodes via the XMLHttpRequest. Confluence does not have any custom ordering for children so we use a shortcut to get the children sorted by name. Its better then no sorting.

Place in top of your page layout template
<style>
.menuitems ul { padding-left: 10px; margin-left: 0px; white-space: nowrap;}
openPageHighlight { background-color: #00FF00 }
</style>

    #macro(childNode $parentPage $depth) 
         
         <li><a onClick="toggleChildren('$parentPage.id'); return false;">
               #if ($parentPage.children.size() > 0)
                   #if ($depth > 0)
                       <img border="0" onClick="togglePlusMinus(this)" src="/confluence/images/icons/tree_minus.gif"></a>
                   #else
                       <img border="0" onClick="togglePlusMinus(this)" src="/confluence/images/icons/tree_plus.gif"></a>
                   #end
               #else
                   <img border="0" onClick="togglePlusMinus(this)" src="/confluence/images/icons/tree_square.gif"></a>
               #end

                #if ($parentPage.id == $helper.page.id)
                    <span class="openPageHighlight">#contentLinkWithAnchor($parentPage 'selectedPageInHierarchy')</span>
                #else
                    #contentLink2 ($parentPage true false)
                #end


                <div id="children$parentPage.id">
               #if ($depth > 0)
                   <ul style="list-style-type: none; padding-left: 10px;">
                   #foreach ($child in $parentPage.sortedChildren)
                      #set ($nextDepth = ($depth - 1))
                      #childNode($child $nextDepth)
                   #end
                   </ul>
               #end
               </div>
            </li>
    #end

    <script language="JavaScript" src="$req.contextPath/includes/js/ajax.js"></script>
    <script language="JavaScript">
    
    function togglePlusMinus(e)
    {
        if (e.src.indexOf("_plus.gif") != -1)
            e.src = "$req.contextPath/images/icons/tree_minus.gif";
        else
            e.src = "$req.contextPath/images/icons/tree_plus.gif";
    }

    function toggleChildren(id)
    {
        var childrenDiv = document.getElementById("children" + id);
        // internet explorer uppercases HTML attributes
        if (childrenDiv.innerHTML.indexOf("list-style-type") != -1 || 
            childrenDiv.innerHTML.indexOf("LIST-STYLE-TYPE") != -1) 
        {
            // simply toggle the visibility of the children div now that we've already fetched it
            if (childrenDiv.style.display == 'block' || childrenDiv.style.display == '')
                childrenDiv.style.display = 'none';
            else
                childrenDiv.style.display = 'block';
        }
        else
        {
            // Set childrenDiv to indicate loading while xml http fetches the actual children list
            childrenDiv.innerHTML = "<ul>Loading ...</ul>";

            xmlhttp = getXmlHttp();
            xmlhttp.open("GET", "/confluence/pages/children.action?pageId=" + id,true);
            xmlhttp.onreadystatechange=function()
            {
                if (xmlhttp.readyState==4) {
                    childrenDiv.innerHTML = xmlhttp.responseText;
                }
            }
            xmlhttp.send(null)
        }
    }

    </script>


This next section creates the column where the tree will live and calls the output macro to generate the tree to the desired depth.

Place in a td directly above the one holding the $body output
               #if ($action.isPrintableVersion() == false)
                  <td width="16%" valign="top">
                  <div class="navmenu">
                        <div class="menuheading">$page.space.name</div>

                        <div class="menuitems" style="padding: 5px;">
                              <ul style="list-style-type: none; margin-left: 0; padding-left: 0">
                               #childNode($page.space.homePage 2)
                              </ul>
                            </div>
                  </div>
                #else
                  <td width="0" valign="top">
                #end

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Jan 06, 2006

    Anonymous says:

    Is there a way to exclude pages? For example to exclude "Home" and show every...
    • Is there a way to exclude pages? For example to exclude "Home" and show everything else?
    • How do I prefent the tree from expanding on page load?

    Thanks in advance

    1. Jan 06, 2006

      Greg Hinkle says:

      The childNode call also passes a depth. This is the depth that the tree should ...

      The childNode call also passes a depth. This is the depth that the tree should be expanded to. The example expands to two levels. Change the depth to 1 to only show the Home children.

      #childNode($page.space.homePage 1)

  2. Jan 09, 2006

    Rogier van der Pol says:

    This will indeed stop the tree from expanding, but it also makes the tree navig...

    This will indeed stop the tree from expanding, but it also makes the tree navigation useless
    When I try to expand a plus sign after setting the childnote call to 1, I receive the following error:
    Cause:
    com.opensymphony.xwork.config.ConfigurationException: There is no Action mapped for namespace /confluence/pages and action name children
    I'll spare you the trace

    Any suggestions?

  3. Aug 26, 2006

    Bhavin says:

    the only issue with this script is .... when i browse to a page which is "4" lev...

    the only issue with this script is .... when i browse to a page which is "4" levels deep, it re-renders the menu on the left such that it is only 2 levels deep and therefore does not show where in the navigation i currently am