Syntax Plugin NsToC, Namespace Table of Contest

A while ago I started a project involving lots of hierar­chi­cally orde­red pa­ges – just like a book with chapters, sub-chap­ters and para­graphs. To add (and up­date whenever a page was ad­ded/re­mo­ved/mer­ged) the ToC re­fe­ren­ces was a nec­ce­sary but quite stu­pid job1). After doing this pesky task for quite a few ti­mes I de­ci­ded to auto­mate it. — Enter „nstoc“.

This plugin offers you the ability to gene­rate a Table Of Con­tents for a na­me­space with an optio­nal depth. It gene­rates a (possi­bly nested) list of head­lines used in all mat­ched pages.

One could say this plugin sees your whole Wiki as one huge docu­ment struc­tured by chap­ters (Wiki name­spaces), sub-chap­ters (the single pa­ges within a name­space) and ap­pro­pri­ate head­lines (H1…H5).


The basic markup is just:

	{{nstoc }}

This will create a nested list of all pages2) in the cur­rent name­space and all sub-na­me­spa­ces. Please note the space3) be­hind the „nstoc“ key­word: For­get­ting it will trigger Do­ku­Wiki's builtin media ren­de­rer which you most pro­bab­ly do not want here.

To limit the output to – say – two levels use

	{{nstoc 2}}

The result will be a list with all H1 and H2 head­lines in the cur­rent na­me­space's pages and all H1 head­lines in the pages of all sub-na­me­spaces of the cur­rent one while

	{{nstoc 3}}

will pro­duce a list with all H1/H2/H3 head­lines in the current na­me­space's pa­ges, all H1/H2 head­lines in the pages of all sub-name­spa­ces of the cur­rent one and all H1 head­lines in the pa­ges of all sub-sub-name­spaces.

Another way to limit the output is to expli­citly name the name­space:

	{{nstoc chapter2}}

This will show the head­lines (with unlimi­ted depth) in the „chapter2“ name­space.

You may, of course, combine the optional name­space and depth ar­gu­ments:

	{{nstoc chapter3 1}}

Here only the H1 head­lines of the pages in „chapter3“ will be shown.


Here are some tips which might be help­ful for you when wor­king with this plugin.


The generated output – or, to be more precise: the order of the ge­ne­ra­ted list – might not always be what you'd expect. The reason for this: You, as a hu­man be­ing4), have a no­tion of meaning while the com­puter just knowns about data. To illu­strate this let's as­su­me you're wri­ting a book. Right now you've fini­shed (or at least crea­ted) this pa­ges:

  1. Preface
  2. Introduction
  3. First Chapter
  4. Second Chapter
  5. Appendix

When using „nstoc“ you'll most probably expect a list like the one above. But, alas, the real result would look like

  • Appendix
  • First Chapter
  • Introduction
  • Preface
  • Second Chapter

Not very helpful, is it? — The reason is simple: The only thing DokuWiki and this plugin has to deal with are (file and namespace) names. But, as it turns out, it's quite easy for you to take this fact to your advan­tage by choo­sing the right page names. For example, name the pages5) like this:

  • 00_preface
  • 01_introduction
  • 02_first_chapter
  • 03_second_chapter
  • 99_appendix

Theoretically you could even ommit all the alphas and just leave the di­gits. But I guess, that would take the compu­teri­sing of your work a bit too far. Any­way, as long as the pa­ge and name­space names sort in the inten­ded order, „nstoc“ will pro­duce useful out­put.

BTW: This discussion applys to name­space names as well. This means, that you should name your name­spaces accor­ding to their inten­ded po­si­tion (i.e. ac­cor­ding to their re­spec­tive posi­tion6) within your over­all pre­sen­ta­tion). If, for exam­ple, the first chap­ter of your book has seve­ral sub-chapters, you should name the name­space „02_first_chap­ter7) and the pa­ges therein e.g. „01_first_sub­ject“, „02_se­cond_sub­ject“ and so on. Of course, the head­lines there­in should be a little more mea­ning­ful for human readers.

Accessible pages

Starting from the 2007-01-08 release of this plugin all pages not acces­sible to the re­spec­tive cur­rent user/reader are omit­ted from the ge­ne­ra­ted list. In other words: Any user will see a ToC con­tai­ning only pages he/she may ac­tually read. This avoids the in­con­ve­nience for your readers seeing a page/head­line in the ToC but when trying to read it get­ting only an „ac­cess denied“ mes­sage.

So, assuming you've setup your access control appro­pria­tely8) you don't have to worry about ex­po­sing (the exis­tence of) pa­ges which your users – or, at least, some of them – are not sup­po­sed to see.

Another benefit for you is that you don't have to mo­dify the pages con­tai­ning the „nstoc“ markup when­ever you add a name­space and/or page. To illu­strate this re­mem­ber our vir­tual book pro­ject out­lined above.

Suppose you've got the preface and second chapter fini­shed while still wor­king on the other parts. And you want any casual reader to see only those fini­shed pa­ges but not the work-in-pro­gress ones. So you'd write in your overview page

	{{nstoc 00_preface}}
	{{nstoc 03_second_chapter}}

Some weeks later the first chapter is ready for public review. To make them ac­ces­sible you'd change the over­view page to

	{{nstoc 00_preface}}
	{{nstoc 02_first_chapter}}
	{{nstoc 03_second_chapter}}

Then turning to chapter seven some time later again you'd change the over­view page:

	{{nstoc 00_preface}}
	{{nstoc 02_first_chapter}}
	{{nstoc 03_second_chapter}}
	{{nstoc 08_seventh_chapter}}

And so on …

Using access control you would initially set the book's name­space to be un­read­able by anyone but yourself. In the overview page you just insert:

	{{nstoc }}

Now, whenever you find one of your book's pages worth for public con­sump­tion you just add a line to your access control like

	book:00_preface @ALL    1

or whatever you feel appro­priate9). You won't have to change the book's over­view page ever again – at least, not to update the „nstoc“ markup, that is. Every­thing is ma­na­ged by this plugin and Doku­Wiki's access con­trol system.

Starting from the 2007-08-15 release of this plugin pages matched by the global 'hidepages' set­ting (i.e. a regu­lar expres­sion10)) will be omitted in the gene­ra­ted list as well11).

Index pages

If the name given after the „nstoc“ keyword resolves to a default page name (i.e. „start“ with an un­mo­di­fied Doku­Wiki in­stal­la­tion) the re­spec­tive name­space is used for ge­ne­ra­ting the ToC but not the page. The same happens if you're poin­ting to a page with the same name as a sub-name­space. In case you're gene­ra­ting a ToC for a name­space that inclu­des sub-name­spaces all those assumed in­dex pages12) are skip­ped as well. This fea­ture is inten­ded to avoid in­dexing pa­ges that are al­ready meant to be kind of over­view pages.

Root page

With earlier releases the root namespace had to be treated espe­cially. Star­ting with the 2007-08-12 release of this plugin the root name­space now is handled al­most as each other name­space. So you could use the basic markup

	{{nstoc }}

to generate a ToC with all available pages in your Doku­Wiki instal­la­tion.

Assuming a fairly structured installa­tion, how­ever, the pa­ges in the root name­space are most pro­bably some kind of star­ting point for one sub-name­space or another. Hence it seems sensible to use „nstoc“ in the root name­space in a more explicit way like

	{{nstoc intro_page}}
	{{nstoc ns1 2}}
	{{nstoc ns2 1}}
	{{nstoc ns3:ns3a}}

Such a markup will exclude the pages in the root name­space but show only those head­lines found in the speci­fied sub-name­spaces.

Numeric namespace names

Some people – as I've been told – do prefer to use nume­ric name­space names such as „1“, „23“ or „456“. Al­though this isn't a pro­blem as such for this plugin you must be care­ful when wri­ting the ns­toc markup. I've sta­ted above that gi­ving a name­space's name is enough to get all head­lines of that name­space (incl. its sub-name­spa­ces) with unli­mi­ted depth. So

	{{nstoc 23}}

should show the headlines of name­space „23“, right? – Wrong: The plugin inter­prets this as a max. depth va­lue of 23 for the cur­rent name­space.

To make sure the „23“ is accepted as the name­space's name you have to use the 2-ar­gu­ments vari­ant i.e. gi­ving the max. depth va­lue as well:

	{{nstoc 23 4}}

Now the namespace called „23“ would get in­dexed up to a nes­ting depth of 4 levels. – Easy, isn't it?

This plugin allows for relative addres­sing the desired name­space as well. Con­si­de­ring the book example above and assu­ming there's a sub-nam­espace in the first chapter called 03_im­por­tant_points let's sup­pose you're in the name­space of the second chapter (i.e. in 03_se­cond_chapter). Now you'd like to pro­vide links to the men­ti­oned pages for your rea­ders. You could do this by either use an abso­lute path like

	{{nstoc :book:02_first_chapter:03_important_points 2}}

or use a rela­tive path like

	{{nstoc ..:02_first_chapter:03_important_points 2}}

With this example it's only a difference of 3 charac­ters. But the dee­per your na­me­spaces are nested the more you save ty­ping. And – as an addi­tio­nal bene­fit – using rela­tive paths lea­ves those links intact if you move the whole book to an­other place: If – for instance – you de­cide to move/re­name the whole book name­space into a new my_books name­space un­der the new name big_bang (or what­ever) the abso­lute path above would no lon­ger show any links while the rela­tive one will still work as ex­pected13).

Besides DokuWiki's : (colon) path sepa­rator this plugin allows the stan­dard UNIX / (slash) as well. Hence the se­cond exam­ple above could be writ­ten

	{{nstoc ../02_first_chapter/03_important_points 2}}

as well. The respec­tive cur­rent name­space can be addres­sed as ./, the pa­rent name­space as ../ and the root name­space as /. This seems to be more intui­tive at least for those who are fami­liar with a shell com­mand­line.


At least as long as the name­space/page struc­ture you're in­dexing by this plugin is like­ly to change you should place the „~~NOCACHE~~“ direc­tive in those fi­les (pa­ges) which con­tain the „nstoc“ markup. That should make sure that the users al­ways get an actual/cur­rent ToC.

Se mere

In other words: just what com­pu­ters were made for.
actually, the head­lines in/of the pages are shown
space, ASCII char #32; not to be con­fu­sed with a blank, ASCII char #255
I hope …
i.e. the files bur not the H1 head­line
or relevance
Note that there will be no collision with the page name 02_first_chapter since the latter inter­nally uses a file­name exten­sion.
what­ever that may mean for your indi­vi­dual in­stal­la­tion
You might find it worth­while to check out the experi­mental ACL Plugin.
see „man 7 regex“ for details
Note that this plugin does not share Doku­Wiki's bug in hand­ling hidden pages if the RegEx is e.g. „0“ but tests the $conf['hidepages'] set­ting pro­perly.
i.e. pages with the $conf['start'] name and pages with the same name as a sub-direc­tory
Please note that the pagemove plugin has problems with both internal and relative links. However, this doesn't affect the nstoc markup since it isn't recognized by pagemove anyway.
/customers/8/6/d/ · Sidst ændret: Y/m/d H:i af philip