Summary: A Simple Dynamic Hierarchical Tree Menu for PmWiki Groups and Pages
Version: 1.00 June 11, 2006
Prerequisites: PmWiki version 2.1.26
Status: Stable
Maintainer: Henrik Bechmann (
Categories: Menus, Layout
Discussion: LinksTreeMenu-Talk

Questions answered by this recipe

How to create hierarchical menus for PmWiki website groups and pages? Note that this solution is Dynamic HTML, so some assembly is required (css, javascript, images, html).


Using this simple tree menu, authors create menus using nested wiki unordered lists. Users see these as menus that progressively open submenus and present further choices. For example, here is a possible sequence of five steps:

Frame 1: Main Wiki Page is first loaded

Frame 2: User selects Folder "About the Market"

Frame 3: User selects SubFolder "Berman Photo Gallery"

Frame 4: User selects Documents "Spring-Summer 2005"

Frame 5: User selects Document "June"

Note that with each selection a new wiki page is presented. You can try it yourself here.

There is no logical limit to the depth of the menus.


Quick install

Here is a quick way to install and try the menus. The full install instructions to the left provide various options.

1. Add the following HTML to a sidebar in your template:

<img style="float:left" 
  src="/common/graphics/document.gif" alt="">
<p>Documents in Folder $Group:</p>

<div id="documentblock">

<img style="float:left" 
  src="/common/graphics/folder.gif" alt="">
<p>Available Folders:</p>

<div id="folderblock">

<p><a id="currentfolderlink" 

<p><a id="currentdocumentlink" 
 href='$PageUrl'>View page</a></p>

<p><a href=
 Edit Folders Menu</a></p>
<p><a href=
 Edit Documents Menu</a></p>

2. Add the following to the <head> section of your template:

<script src="/common/scripts/linkstreemenu.js" 
<link rel="stylesheet" type="text/css" 

3. Modify the onload attribute of the body element of your template as follows:

<body onload="initmenus();">

4. Create the following directories on your server:


5. Download linkstreemenu.zipΔ, and distribute the contents as follows:

  • arrowdown.gif, arrowright.gif, disc.gif, document.gif, and folder.gif  to /common/graphics/
  • linkstreemenu.js  to /common/scripts/
  • linkstreemenu.css  to /common/styles/

Then create your menus according to the patterns specified in Menu Maintanance below.


To integrate the links tree menus into your template (skin) do the following:

1. Add the following HTML to a sidebar in your template (the decoration and custom name formatting procedures have been omitted - beyond the scope of this recipe):

<img style="float:left" src="/common/graphics/document.gif" alt="">
<p>Documents in Folder $Group:</p>

<div id="documentblock">

<img style="float:left" src="/common/graphics/folder.gif" alt="">
<p>Available Folders:</p>

<div id="folderblock">

Note that wiki pages containing the Documents Menu and the Folders Menu are imported into named blocks.

2. Make sure that the current Group Default Page url and the Current Page url are both available to javascript in named elements in the skin. These url strings will be accessed by javascript to find menu items to highlight. For example, somewhere in the template have:

<a id="currentfolderlink" 

(as, say, part of a breadcrumb trail of where the user is)


<a id="currentdocumentlink" href='$PageUrl'>View page</a> (as, say, part of the author's edit menu)

3. Somewhere on the author's menu of your template make the FoldersMenu and DocumentsMenu wiki pages available for edit (see examples of menu lists below) so that authors and administrators can create the menus. Note that there is only one FoldersMenu page per wiki, but many DocumentsMenu pages -- one for each group.

<a href='$ScriptUrl/$DefaultGroup.FoldersMenu?action=edit'>
  Edit Folders Menu</a>
<a href='$ScriptUrl/$Group/DocumentsMenu?action=edit'>
  Edit Documents Menu</a>

4. Add "initmenus()" to the value of the onload attribute of the HTML body element of the template, so that it looks like this:

<body onload="initmenus();">

This causes the menus to be initialized, including the current document and folder to be highlighted, the correct icons to be displayed, and the correct submenus to be opened. Submenus of currently selected items are opened, and of course submenus containing currently selected items are opened.

5. Download linkstreemenu.zipΔ, and distribute the contents as follows:

6. From in #5, incorporate the javascript in linkstreemenu.js into a javascript file attached to your template, or add the file to a common directory (eg. /common/scripts/linkstreemenu.js) and add the line <script src="/common/scripts/linkstreemenu.js" type="text/javascript"></script> to your template file.

7. From in #5, incorporate the css in linkstreemenu.css into your template. For example add the css to an existing css file, or place the linkstreemenu.css file into a common css directory (eg. /common/styles/linkstreemenu.css) and add the line <link rel="stylesheet" type="text/css" href="/common/styles/linkstreemenu.css"> to your template file.

8. From in #5, place the image files (arrowright.gif, arrowdown.gif, disc.gif) into a common graphics file directory on your web server (eg. /common/graphics). Optionally, if you want to use them, place the image files folder.gif and document.gif into the same directory.

9. If you have put the image files of #8 anywhere other than /common/graphics/, then go back and correct the references to these files: in the javascript of #6 and the css of #7, find the "url(...)" references, and correct the path names to correspond to the path you used. In the HTML of #1 correct the "src" attributes of the "img" elements.

Menu Maintenance

To maintain the menus, maintain unordered nested lists of wikilinks in $DefaultGroup.FoldersMenu for the Folder menu and the various $Group.DocumentsMenu pages for the Documents Menus. All items in the unordered lists must be wiki links, and the first item of the topmost list in each page must be used to identify the unordered list as a munulist, like this:

*%list menulist%[[SomeGroup.SomePage]]

...with the appropriate presentations to the user depending on the type of list.

Here are list examples from the menu examples shown above in the Description of this recipe:

*%list menulist%[[Market.FrontPage | Market (Main)]]
*[[About The Market(.FrontPage)]]
**[[Market Finances(.Front Page)]]
**[[Berman Photo Gallery(.Front Page)]]
**[[More Photo Galleries(.Front Page)]]
*[[Vendors(.Front Page)]]
**[[(Vendors.)Front Page|+]]
**[[Vendor Notebook(.FrontPage)]]
**[[Vendor Guidelines(.Front Page)]]
*[[Local Producers(.FrontPage)]]
*[[Weekly Market Notes(.FrontPage)]]
**[[Weekly Market Notes Library(.FrontPage)]]
*[[A Taste Of The Market(.Front Page)]]
**[[News 2006(.FrontPage)]]
**[[News 2005(.FrontPage)]]
**[[News 2004(.FrontPage)]]
*[[Library Of Articles(.FrontPage)]]
*%list menulist%[[Front Page|+]]
*[[(Berman Photo Gallery.)Fall-Winter 2004( - Aug-Sep)]]
**[[(Berman Photo Gallery.Fall-Winter 2004 - )Aug-Sep]]
**[[(Berman Photo Gallery.Fall-Winter 2004 - )Nov-Dec]]
**[[(Berman Photo Gallery.Fall-Winter 2004 - )Dec-Jan]]
*[[(Berman Photo Gallery.)Spring-Summer 2005( - Mar-Apr)]]
**[[(Berman Photo Gallery.Spring-Summer 2005 - )Mar-Apr]]
**[[(Berman Photo Gallery.Spring-Summer 2005 - )May-Jun]]
**[[(Berman Photo Gallery.Spring-Summer 2005 - )June]]
**[[(Berman Photo Gallery.Spring-Summer 2005 - )June And Around The Park]]
**[[(Berman Photo Gallery.Spring-Summer 2005- )July]]
*[[(Berman Photo Gallery.)Fall 2005( - September)]]
**[[(Berman Photo Gallery.Fall 2005 - )September]]
**[[(Berman Photo Gallery.Fall 2005 - )October]]

Note that in some cases the first submenu url reference of a parent item is identical to that parent item. For example:

*[[(Berman Photo Gallery.)Spring-Summer 2005( - Mar-Apr)]]
**[[(Berman Photo Gallery.Spring-Summer 2005 - )Mar-Apr]]

This causes the menu system to jump to the first sub item when the user selects the parent (the javascript searches the list from the bottom up to identify the current page/group).

To force a submenu to be open even if neither its parent nor any of its members is selected, qualify the parent (as item) and the submenu (as list) with "menuopen", like this:

*%item menuopen%[[(Berman Photo Gallery.)Spring-Summer 2005( - Mar-Apr)]]
**%list menuopen%[[(Berman Photo Gallery.Spring-Summer 2005 - )Mar-Apr]]

The "item menuopen" causes the downarrow; the "list menuopen" causes the submenu to be displayed.

Release Notes

If the recipe has multiple releases, then release notes can be placed here. Note that it's often easier for people to work with "release dates" instead of "version numbers".

See Also

Quick Page Table Of Contents



See discussion at LinksTreeMenu-Talk

User notes? : If you use, used or reviewed this recipe, you can add your name. These statistics appear in the Cookbook listings and will help newcomers browsing through the wiki.