New module release — Simple Table of Contents

I just released a new module for Drupal 7.x. Titled Simple Table of Contents, the module provides an easy and automatic way to add a table of contents to all of your content.

Why a new module?

There are a few other table of contents modules for Drupal, namely TableOfContents and TOC Filter. Unfortunately, besides being relatively unstable in the case of TableOfContents, there are a number of downsides to both modules, at least in certain use cases:

  • Work/User input - by relying on the Drupal filter system, both modules transform special user-embedded tokens into a table of contents. Users must manually enter these tokens and they are saved in the database along with the content. In the event that you no longer require the modules, removing all of the tokens can be a hassle.
  • Simplicity/Selectivity - another downside of the filter system, the token to table of contents generation process must be configured per text format and will run for all text passed through that format.
  • Generation method - both modules use regular expressions for searching through HTML, a process which is generally frowed upon (as it can lead to the corruption on your very soul).

How it works

Simple Table of Contents is, as the name implies, relatively simple. The module implements hook_node_view() which allows it to act on nodes as they are being assembled. Simple Table of Contents checks if the node has a body and, if it does, it injects a token into the body's HTML.

Once the token has been injected, the body's HTML is passed to a function which uses PHP's DOM API to perform a number of operations, such as:

  • Finding any header (<h2> to <h6>) tags
  • Adding unique IDs to each of the headers, making them suitable for use as anchors
  • Generating a table of contents
    • Building a tree of nested unordered lists which represent the header's hierarchy
    • Linking each of the list items to its associated header
    • Replacing the token with the table of contents

The modified HTML is then used to overwrite the node's body field which then goes on to be rendered into a page.

The module is still in its infancy and may be have a few issues (although it does come with a suite of 86 functional tests which it passes!) or be missing a few features. If you find a bug or would like to see some sort of additional functionality added to the module, please post in the Simple Table of Contents issue queue.