• Custom Plugin
  • |
  • PHP
  • |
  • WordPress
  • |
  • WPCodebox

Automatic Table of Content for Your WordPress Posts, Conditional Auto Insert before the First H2

Creating a Conditional Table of Contents for WordPress Posts. When enhancing the readability of long-form content, including a Table of Contents (TOC) is beneficial for your readers. In WordPress, you can automatically generate and insert a TOC for single post entries that have structural headings (<h2> and <h3>) using the DOMDocument class. However, to avoid clutter and maintain relevance, showing the TOC only when there are enough headings is prudent. Here, we’ll demonstrate how to achieve this by showing the TOC only if there are more than two <h2> elements in your post content.


Add it to WPCodebox or in your functions.php

Type: PHP

<?php 

// v2.0
// Date: Sunday, June 02, 2024
// Author: Ruhani Rabin
//
//

add_filter( 'the_content', function ( $content ) {
    // This snippet requires the DOMDocument class to be available.
    if ( ! class_exists( 'DOMDocument' ) ) {
        return $content;
    }

    if ( ! is_single() || ! in_the_loop() || ! is_main_query() ) {
        return $content;
    }

    $dom = new DOMDocument();
    // Prevent warnings caused by HTML5 tags
    libxml_use_internal_errors(true);
    $load_content = mb_convert_encoding( $content, 'HTML-ENTITIES', 'UTF-8' );
    $dom->loadHTML( $load_content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD );
    libxml_clear_errors();

    $xpath = new DOMXPath( $dom );
    $h2_headings = $xpath->query('//h2');

    if ( $h2_headings->length > 2 ) {
        $headings = $xpath->query('//h2 | //h3');

        if ( $headings->length > 0 ) {
            // Find the first <h2> element
            $first_h2 = $h2_headings->item(0);

            // Create the table of contents with title
            $headings_list = '<div class="table-of-contents-container" id="toc"><p class="toc-title">Table of Contents</p>';
            $headings_list .= '<ul class="table-of-contents" style="list-style: none;">';
            foreach ( $headings as $heading ) {
                $heading_id = $heading->getAttribute('id');
                if ( empty( $heading_id ) ) {
                    // Generate a heading id and add it to the heading.
                    $heading_id  = sanitize_title( $heading->nodeValue );
                    $heading->setAttribute('id', $heading_id);
                }
                $heading_text = $heading->nodeValue;
                $padding_class = $heading->tagName === 'h3' ? ' toc-h3-padding' : '';
                $headings_list .= '<li class="' . $padding_class . '"><a href="#' . $heading_id . '">' . $heading_text . '</a></li>';
            }
            $headings_list .= '</ul></div>';

            // Create a new DOM element for the table of contents
            $dom_toc = $dom->createDocumentFragment();
            $dom_toc->appendXML($headings_list);

            // Insert the table of contents before the first <h2>
            $first_h2->parentNode->insertBefore($dom_toc, $first_h2);

            // Save the modified content
            $content = $dom->saveHTML();
        }
    }

    return $content;
});

// Add some CSS for padding and title styling
add_action('wp_head', function() {
    echo '<style>
        .table-of-contents-container {
            display: block;
        }
        .table-of-contents ul {
            list-style: none !important; 
            padding: 0;
        }
        .table-of-contents .toc-h3-padding {
            padding-left: 20px;
        }
        .toc-title {
            font-weight: bold;
            font-size: 21px;
            margin-bottom: 10px;
        }
    </style>';
});


More Codes

WordPress Cron Job Cleanup Made Easy – My Cron Manager

Effortlessly manage WordPress cron jobs with My Cron Manager. Clean up, view, and control tasks to boost site performance.

Quick Access Menu – Custom Dropdown for WP Admin Bar with Options Page

Improve functionality and aesthetics of your WordPress site with custom dropdowns, date replacement, and source code highlights. No plugins needed!

Dynamic Date Replace on WordPress Post Title, Excerpt, Content, Menu Items

“Dynamic Date Replace Plugin for WPCodeBox: Easily add dynamic date info to your WordPress site’s content, titles, and menu items with shortcodes!”