Summary: Adds a dynamically generated sitemap to PmWiki.
Version: 20160803
Prerequisites: PmWiki 2.2.58 and later
Status: beta
Maintainer: Eemeli Aro


In essence, this is a perversion of the concept of a sitemap, turning it inside out. Your sitemap will define the navigation and thereby the structure of your wiki. New pages will automatically be added to the sitemap.

The Group > Page structure of the wiki will be completely unchanged, giving you the benefits of both worlds: a simple file & URL structure and a navigation structure of arbitrary depth and complexity.

Also features authorization levels, batch updates, result caching and a high degree of customization.

To install this recipe:

  • download sitemapper.phpΔ to your cookbook directory
  • add the following line to your config.php file:

What it does

When viewing a page, Sitemapper can read a page in the wiki (by default Main.Sitemap) and parse it in a similar manner as WikiTrails are parsed, creating a tree of its contents. This tree is then searched for mentions of the current page and hierarchical navigation elements are generated from it, as well as a breadcrumb trail similar to path trails.

When saving a page not included on the sitemap, the sitemap is searched for the main page of the group that page belongs to. If found, the saved page will be added to the sitemap as a new child of that page. If not found, the page will be added to an "Uncategorized" group in the sitemap. It's also possible to trigger this feature in batch mode, adding all the pages in a wiki to the sitemap.

For reasons of speed, Sitemapper generates HTML and not wiki markup and caches its results. This allows very fast operation even on sites with hundreds of pages and sitemap entries of the form [[target|+]]. The HTML generation is highly configurable, however.


Here's a complete list of the additions made to the markup, and their functions.

(:sm-nav page=abc depth=[+-]# fmt=def:)
Insert a navigation element. All parameters are optional.
page= Display navigation for the defined page. Default is the current page.
depth= Starting depth of navigation. If preceded by '+' or '-', depth is relative to the given page; if just a number, depth is absolute. Default is '+0'.
fmt= Comma-delimited list of the values 0, 1 and 2 defining how to show different levels of navigation.
  • 0: show only direct ancestors
  • 1: expand this level if it contains a direct ancestor
  • 2: expand this level always
A few examples may clarify things a bit:
fmt=0,1 -- show this page and its direct children
depth=+1 fmt=1,1 -- show the children and grandchildren of this page
depth=1 fmt=2,2 -- show the top two levels of the sitemap
Insert the breadcrumb trail(s) of this page. If the page is listed multiple times in the sitemap, each trail is shown on a separate line.
(:sm-alias Group.Page:)
Change the default page for navigation elements to Group.Page and show this page as a child of that page.
Don't show where this page is in the navigation.
Don't show anything for the template function SmPrintBottom.
(:sm-hide:) and (:sm-show:)
In the sitemap document, begin and end a section that is only displayed for authorized users.

Skin template functions

You may add the following lines in the appropriate places to your pmwiki.tmpl or other template file to display navigation elements:

<!--function:SmPrintNav [options]-->
Same output as (:sm-nav:), with the same optional parameters.
Same output as (:sm-trail:). Displays nothing for the Sitemap root page.
Same output as (:sm-nav depth=1 fmt=2,1:).
Same output as (:sm-nav depth=## fmt=0,1:) where ## depends on whether the page has (+0) or doesn't have (-1) children

Using the basic PmWiki skin, probably the most appropriate places are immediately before the SideBar for the top levels and immediately before <!--PageTitleFmt--> for the bottom levels and the breadcrumb trail, as seen in this exampleΔ.


The recipe adds two new actions for batch updating of pages.

Read all pages in the wiki and add those missing from the sitemap by group in alphabetical order. Displays a log of its actions.
Read all pages in the wiki and add the group main pages missing from the sitemap in alphabetical order. Displays a log of its actions. When adding a large number of pages it's probably easier to first add the groups, organise those, and then add the rest using sitemapupdate.


The following variables may be set in your config.php file to configure the way Sitemapper works.

File locations

$SmCacheDir = $WorkDir;
The directory in which Sitemapper stores the cached sitemaps, Sitemapper-Authorized,cache and Sitemapper-Public,cache. Set to '' if you wish to diable caching.
$SmSitemapPagename = 'Main.Sitemap';
The sitemap page, a user-editable wiki page. The source of all the structure information.
$SmRootPagename = 'Main.HomePage';
The name of the page that acts as the root of the sitemap. Used in the default sitemap text and in the breadcrumb trail.
$SmUncategorizedPagename = 'Site.Uncategorized';
The name of the page under which uncategorized pages will be listed.


$SmAuthorized = CondAuth( $SmSitemapPagename, 'edit' );
Used for determining a user's right to view content inside (:sm-hide:) ... (:sm-show:) tags and in executing batch updates. In order to change this to requiring a AuthUser logged-on user, use the following:
$SmAuthorized = ( @$GLOBALS['AuthId'] > '' );
Note: This variable is not used when displaying the contents of the sitemap page itself. By default (:sm-hide:) is interpreted as (:if auth edit:). If you need to change that, you'll need to manually edit line 50 of sitemapper.php.

Automatic sitemap update

$EnableSmUpdate = 1;
Is automatically updating the sitemap on page save allowed? A more complex calculation is also allowed (as in $SmAuthorized by default), for example to implement a level of authorization.
$EnableSmBatchUpdate = 1;
Is batch updating of pages allowed? Also requires that $EnableSmUpdate is true. A more complex calculation is also allowed (as in $SmAuthorized by default), for example to implement a level of authorization.
$EnableSmRemoveOnDelete = 1;
When a page is deleted, should it also be removed from the sitemap?
$EnableSmWriteDefaultOnEmpty = 1;
If a sitemap isn't found on the sitemap page, should one be started with the default text?
$SmDefaultSitemapText = "\n* [[$SmRootPagename|+]]\n** [[$SmSitemapPagename|+]]\n* [[$SmUncategorizedPagename|+]]\n";
$SmExcludePatterns = $SearchPatterns['default'];
Patterns that the page name will be matched against, and if true, the page will not be added to the sitemap when saved.


The default layout applied to Sitemapper elements. Probably should be overwritten to fit your site and skin.
$SmRootLink = "<a href='$ScriptUrl'>Home</a>";
The HTML string to prepend to the breadcrumbs trail.
$SmTrailSeparator = ' &raquo; ';
The HTML string that acts a separator for the breadcrumb trail.
$SmBottomShowlevel = 2;
At what minimum level should the bottom navigation be shown? '2' means that a child item in the top level will have its children shown in the bottom level navigation. '1' means that the bottom level navigation will also be shown for top-level items. Greater values are also allowed, for whatever reason you may want them.


  • This recipe has been developed for a specific site on which it may seen in use:
  • The sitemap is completely user-configurable and editable. It's perfectly allowed to have the same page as its own child, nonexisting pages, sections links, URL links, whatever.
  • Sitemapper acts in a similar manner to pagelists when $EnablePageListProtect is set to 0. In order to hide pages, you'll need to add (:sm-hide:) ... (:sm-show:) tags to your sitemap and define an appropriate $SmAuthorized value.
  • You may wish to set { display:none; } for Site.EditForm, as the edit box clears both edges and may get pushed rather far down the page.

Features under development

Release Notes

  • 20160803 : update for PHP 5.5 (by Petko)
  • 0.5.2 / 2008-09-10
    • bug fixes: url link titles, removing pages
  • 0.5.1Δ / 2008-06-26
  • 0.5 / 2008-01-15
    • no bespoke link generation -- support section & URL links
    • support multiple mentions on sitemap
    • markup directives: navigation, cloak, alias
    • autohandle unlisted group subpages
    • bug fixes / code rewrite
  • 0.4 / no public release
    • reworked navigation generation
    • blank sitemap handling now in SmReadMap
    • reduced global variables
    • bug fix: titling for [[group/]] links
  • 0.3 / 2007-08-17 -- first public release


  • I just installed a fresh new pmwiki and wanted to test your sitemapper recipe. All the option you mentioned here work for me except for the update-function ?action=sitemapupdate. If I type in Main/Sitemap?action=sitemapupdate nothing changed. I can't figure out why...MatthiasGünther October 01, 2008

Mod: Icons in breadcrumb trail / Sitemap title for current page

I wouldn't dare to alter the original version, but feel free to integrate my modifications (marked # fsmod in source code):

  • added gifs as icons to bread crumb trail, if they exist in uploads (eg. Main/MyPage.gif for page Main.MyPage)
usage: (:sm-trail icons:) resp. <!--function:SmPrintTrail icons -->
  • added markup to display the page title given in Sitemap as heading of the current page
usage: e.g. (:sm-title 2:) resp. <!--function:SmPrintTitle 2 --> for heading <h2> (default <h1>)

Frank April 28, 2009

See Also


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.