soo_toc Page 1 of 3



Textpattern plugin that automatically generates tables of contents for articles.


soo_toc version 0.1.5, 2.1 KB
(If it won’t install try the compressed version)

Preview soo_toc code


This is a Textpattern plugin. It contains one tag, <txp:soo_toc />. This tag can be placed just about anywhere and will automatically generate a table of contents for any article it finds, so long as that article contains HTML headings (h1, h2, etc.) with id attributes. Of course it requires an article context, either list or individual.

It’s much like the cbs_article_index plugin. However, <txp:soo_toc /> offers nested list output, heading-level filtering, and a choice of relative or absolute URLs. If you don’t need those features, you might prefer cbs_article_index for its lighter footprint.


<txp:soo_toc />


The first five are standard Textpattern attributes; only the last two (level and full_url) are plugin-specific.



Can be used in an article body, in a page, or in a form. If used with relative URLs (the default setting) it requires an individual article context. If used in an article list, or on a page in which the base element indicates anything other than current page, the full_url attribute must be set to true (or anything other than 0). (See Relative vs. Absolute URLs, below.)

The article headings

Only headings that have an id attribute will be included. This is to give the links in the table of contents something to point to. In Textile, you can apply the id attribute like this:

h3(#example). Example

to produce:

<h3 id="example">Example</h3>


The level attribute allows you to restrict which heading levels to include in the table of contents. For example, level="3" will restrict output to h1, h2, and h3 headings. The default value is 6, show all headings.

You might use this to have both a full and a concise table of contents, one in the sidebar and the other in the article body. Or combine with a bit of javascript to allow the user to expand or collapse the table of contents.

Relative vs. absolute URLs

The default output uses same-page relative URLs (e.g. href="#id_name"), which will only work correctly in an individual article context. To get absolute (full) URLs instead, set the full_url attribute to true (or any value other than 0).

If you use a base tag to point to the site root (or anything other than the current page), you will also need to use full URLs. (N. B., such usage of base is, strictly speaking, incorrect.)

Nested output

If the wraptag is ul (the default value) or ol, and if the article has different levels of headings, the table of contents will be a nested list. For example, given the following article headings (shown in Textile):

h2(#foo). Foo
h3(#bar). Bar

the plugin will produce, using default attributes:

<ul class="toc">
	<li><a href="#foo">Foo</a>
		<li><a href="#bar">Bar</a></li>

For this nested output to make sense, the article’s heading structure must also make sense. In particular:

Because the plugin ignores headings with no id attribute, you could get unexpected results (and possibly XHTML validation errors) if you are inconsistent about assigning id to headings.



The plugin runs a preg_match_all search on the article’s HTML body, and another preg_match on each heading. Theoretically this could be a performance concern in some situations, particularly in an article list context.


This plugin is very similar to the cbs_article_index plugin (didn’t realize this when I wrote it), but with more options for output and control.

Version 0.1.5, 2017-02-15

Version 0.1.4, 2009.4.26

Version 0.1.3, 2008.2.03

Version 0.1.2, 2008.2.03

Version 0.1.1, 2008.1.29

Version 0.1, 2008.1.26