In my previous post about adding breadcrumb navigation to WordPress blogs, I covered how it helps search engines index your site. Today, I’d like to introduce a method for adding a table of contents to your articles. What is a table of contents? If you frequently visit Baidu Zhidao, you’ll notice the article sidebar features a table of contents. Denis’s blog also has table of contents in articles. So what purpose does it serve? Simply put: first, clicking on a heading jumps you to the corresponding section; second, it makes the article’s structure and flow much clearer.
There are only a handful of WordPress table of contents plugins. The free ones are cumbersome to use and overly complex with their configurations. Denis offers a paid plugin, but I still hold to my original principle — use as few plugins as possible and integrate functionality directly into the theme.
Here’s how to do it:
1. Add the Code
As usual, add the following code to your theme’s functions.php file:
// Article Table of Contents
function article_index($content) {
$matches = array();
$ul_li = '';
$r = "/<h3>([^<]+)<\/h3>/im";
if (preg_match_all($r, $content, $matches)) {
foreach($matches[1] as $num = >$title) {
$content = str_replace($matches[0][$num], '<h2 id="title-'.$num.'">'.$title.'</h2>', $content);
$ul_li. = '<li><a href="#title-'.$num.'" title="'.$title.'">'.$title."</a></li>\n";
}
$content = "\n<div id=\"article-index\">
<b>[Table of Contents]</b>
<ul id=\"index-ul\">\n".$ul_li."</ul>
</div>\n".$content;
}
return $content;
}
add_filter("the_content", "article_index");
2. Add CSS:
With the code in place, styling is equally important. You can write your own CSS or use the styles provided below:
#article-index {background:#F7F7F7;-moz-border-radius: 6px 6px 6px 6px;border: 1px solid #DEDFE1;float: right;margin: 5px 0 5px 15px;padding: 0 6px;width: 280px;line-height: 24px;}
#article-index b {border-bottom: 1px dashed #DDDDDD;display: block;line-height: 30px;padding: 0 4px;}
#index-ul {margin: 0;padding-bottom: 5px;}
#index-ul li {background: none repeat scroll 0 0 transparent;list-style-type: disc;padding: 0;margin-top: 5px;margin-bottom: 5px;margin-left: 20px;}
#index-ul a{text-decoration:none;}
3. How to Use:
I recall that Denis’s plugin cascades from H1 through H6 tags, which I don’t think works very well. So I changed it to use the </h3> tag, which corresponds to “Heading 3” in the editor. When writing an article, simply add a heading with the </h3> tag for each section. If you don’t want a table of contents for a particular article, just don’t use the </h3> tag. A small note: if you want to customize your heading styles, modify the h2 in your theme’s stylesheet, not h3.
4. Limitations and Suggestions
- Cannot generate multi-level nested table of contents
- If your theme has article pagination, the table of contents won’t be able to extract headings from the second page onward
- If you need multi-level nesting, you might want to try a plugin. I’ll write some articles later specifically recommending such plugins