• 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

Shell/Bash Script Migrating WordPress – Find and Replace all Instance of Domain Name in WordPress or MySQL Database

Automate WordPress Domain Migration with our Shell Script. Easily Find & Replace all instances of your old domain in the MySQL database. Try it now!

How to Add “NEW”, “UPDATED”, and “OUTDATED” Badges to Your WordPress Posts

Enhance your WordPress posts with “NEW,” “UPDATED,” and “OUTDATED” badges! Keep your content fresh and organized for better user experience.

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!