Dynamic Table of Contents for WP Posts
Learn how to dynamically add a Table of Contents to WP posts using filters and modify single templates for full functionality.
A dynamic Table of Contents (TOC) improves navigation and readability for long-form WordPress content. Using the the_content
filter and a user-controlled option, you can insert a TOC automatically before your post content. Here’s how to do it step by step.
Step 1: Add the TOC Logic to functions.php
This snippet dynamically generates and inserts a TOC based on the post’s headings (<h1>
to <h6>
):
// Check if the Table of Contents option is enabled
$enable_toc = get_option('_horizon_enable_toc', false);
if ($enable_toc) {
// Hook the function to 'the_content' filter to modify post content
add_filter('the_content', 'horizon_generate_toc', 10, 1);
}
/**
* Generate a Table of Contents from the content.
*
* @param string $content The post content.
* @return string Modified content with a table of contents.
*/
function horizon_generate_toc($content) {
// Match all headings in the content (h1, h2, h3, etc.)
preg_match_all('/<h([1-6])[^>]*>(.*?)<\/h[1-6]>/', $content, $matches, PREG_SET_ORDER);
if (empty($matches)) {
return $content; // No headings found, return content as is
}
// Start building the Table of Contents
$toc = '<div class="toc"><h2>Table of Contents</h2><ul>';
foreach ($matches as $match) {
$level = $match[1]; // Heading level (1-6)
$heading_text = strip_tags($match[2]); // Heading content
$id = sanitize_title($heading_text); // Generate a URL-friendly ID
// Add an ID to the heading tag for anchor linking
$content = str_replace($match[0], '<h' . $level . ' id="' . $id . '">' . $match[2] . '</h' . $level . '>', $content);
// Add the heading to the TOC list
$toc .= '<li class="toc-level-' . $level . '"><a href="#' . $id . '">' . $heading_text . '</a></li>';
}
$toc .= '</ul></div>';
// Insert the TOC at the beginning of the content
$content = $toc . $content;
return $content;
}
Step 2: Enable or Disable the TOC Option in WordPress
To give users control, add a toggle option in the WordPress admin. Use the following code to register the setting:
// Add a TOC option in the Settings > General page
add_action('admin_init', function() {
register_setting('general', '_horizon_enable_toc');
add_settings_field(
'_horizon_enable_toc',
'Enable Table of Contents',
function() {
$value = get_option('_horizon_enable_toc', false);
echo '<input type="checkbox" name="_horizon_enable_toc" value="1"' . checked(1, $value, false) . '> Enable';
},
'general'
);
});
This creates a checkbox in the Settings > General page. When checked, the TOC will be enabled.
Step 3: Ensure Your Single Template Supports Filters
To apply the the_content
filter, your single.php
template must include the WordPress loop. Add this to your theme if it’s missing:
if ( have_posts() ) {
while ( have_posts() ) {
the_post();
the_content(); // Outputs filtered content with the TOC
}
}
Conclusion
With the above setup, you can dynamically insert a Table of Contents for WordPress posts using the the_content
filter. By adding a toggle option, you provide users the flexibility to enable or disable the TOC as needed. This approach ensures enhanced navigation, improved SEO, and better user experience.