创建自定义TOC

<?php
/**
 * Dynamic Table of Contents Generator for WordPress
 * Add this to your functions.php file
 */

// Function to generate dynamic table of contents
function generate_dynamic_toc($content) {
    // Extract headings (h2, h3, h4) from content
    preg_match_all('/<(h[2-4])[^>]*>(.*?)<\/h[2-4]>/i', $content, $headings);
    
    if (empty($headings[0])) {
        return $content; // Return original content if no headings found
    }
    
    $toc_html = '<div class="table-ysxin dynamic-toc">';
    $toc_html .= '<p><strong>Table of Contents</strong></p>';
    $toc_html .= '<ul>';
    
    $updated_content = $content;
    
    foreach ($headings[0] as $index => $full_heading) {
        $heading_level = $headings[1][$index]; // h2, h3, h4
        $heading_text = strip_tags($headings[2][$index]);
        
        // Generate unique ID from heading text
        $heading_id = sanitize_title($heading_text);
        
        // Ensure unique IDs by adding index if needed
        $heading_id = $heading_id . '-' . ($index + 1);
        
        // Add ID to the heading in content
        $new_heading = str_replace('>', ' id="' . $heading_id . '">', $full_heading);
        $updated_content = str_replace($full_heading, $new_heading, $updated_content);
        
        // Add to TOC with proper nesting
        $indent_class = '';
        if ($heading_level == 'h3') {
            $indent_class = ' class="toc-h3"';
        } elseif ($heading_level == 'h4') {
            $indent_class = ' class="toc-h4"';
        }
        
        $toc_html .= '<li' . $indent_class . '><a href="#' . $heading_id . '">' . $heading_text . '</a></li>';
    }
    
    $toc_html .= '</ul>';
    $toc_html .= '</div>';
    
    // Insert TOC after first paragraph or at the beginning
    $paragraphs = explode('</p>', $updated_content, 2);
    if (count($paragraphs) > 1) {
        $updated_content = $paragraphs[0] . '</p>' . $toc_html . $paragraphs[1];
    } else {
        $updated_content = $toc_html . $updated_content;
    }
    
    return $updated_content;
}

// Hook to automatically add TOC to single posts
add_filter('the_content', 'auto_add_toc_to_content');

function auto_add_toc_to_content($content) {
    // Only add TOC to single posts (not pages, archives, etc.)
    if (is_single() && in_the_loop() && is_main_query()) {
        return generate_dynamic_toc($content);
    }
    return $content;
}

/**
 * Alternative: Shortcode method
 * Use [toc] shortcode to manually place TOC anywhere in your content
 */
add_shortcode('toc', 'toc_shortcode');

function toc_shortcode($atts) {
    global $post;
    
    $attributes = shortcode_atts(array(
        'title' => 'Table of Contents',
        'levels' => '2,3,4' // Which heading levels to include
    ), $atts);
    
    $content = $post->post_content;
    $levels = explode(',', $attributes['levels']);
    $heading_pattern = '<(h[' . implode('', $levels) . '])[^>]*>(.*?)<\/h[' . implode('', $levels) . ']>';
    
    preg_match_all('/' . $heading_pattern . '/i', $content, $headings);
    
    if (empty($headings[0])) {
        return ''; // Return empty if no headings found
    }
    
    $toc_html = '<div class="table-ysxin dynamic-toc">';
    $toc_html .= '<p><strong>' . esc_html($attributes['title']) . '</strong></p>';
    $toc_html .= '<ul>';
    
    foreach ($headings[0] as $index => $full_heading) {
        $heading_level = $headings[1][$index];
        $heading_text = strip_tags($headings[2][$index]);
        $heading_id = sanitize_title($heading_text) . '-' . ($index + 1);
        
        $indent_class = '';
        if ($heading_level == 'h3') {
            $indent_class = ' class="toc-h3"';
        } elseif ($heading_level == 'h4') {
            $indent_class = ' class="toc-h4"';
        }
        
        $toc_html .= '<li' . $indent_class . '><a href="#' . $heading_id . '">' . esc_html($heading_text) . '</a></li>';
    }
    
    $toc_html .= '</ul>';
    $toc_html .= '</div>';
    
    return $toc_html;
}

/**
 * Method 3: Template function for manual placement
 * Call this function in your single.php template
 */
function display_post_toc($post_id = null) {
    if (!$post_id) {
        global $post;
        $post_id = $post->ID;
    }
    
    $content = get_post_field('post_content', $post_id);
    
    preg_match_all('/<(h[2-4])[^>]*>(.*?)<\/h[2-4]>/i', $content, $headings);
    
    if (empty($headings[0])) {
        return; // Don't display anything if no headings found
    }
    
    echo '<div class="table-ysxin dynamic-toc">';
    echo '<p><strong>Table of Contents</strong></p>';
    echo '<ul>';
    
    foreach ($headings[0] as $index => $full_heading) {
        $heading_level = $headings[1][$index];
        $heading_text = strip_tags($headings[2][$index]);
        $heading_id = sanitize_title($heading_text) . '-' . ($index + 1);
        
        $indent_class = '';
        if ($heading_level == 'h3') {
            $indent_class = ' class="toc-h3"';
        } elseif ($heading_level == 'h4') {
            $indent_class = ' class="toc-h4"';
        }
        
        echo '<li' . $indent_class . '><a href="#' . $heading_id . '">' . esc_html($heading_text) . '</a></li>';
    }
    
    echo '</ul>';
    echo '</div>';
}

/**
 * CSS for styling the dynamic TOC
 * Add this to your theme's style.css or enqueue it properly
 */
function enqueue_toc_styles() {
    if (is_single()) {
        wp_add_inline_style('your-theme-style', '
            .table-ysxin.dynamic-toc {
                background: #f9f9f9;
                border: 1px solid #ddd;
                padding: 20px;
                margin: 20px 0;
                border-radius: 5px;
            }
            
            .table-ysxin.dynamic-toc p {
                margin: 0 0 15px 0;
                font-size: 16px;
            }
            
            .table-ysxin.dynamic-toc ul {
                margin: 0;
                padding: 0;
                list-style: none;
            }
            
            .table-ysxin.dynamic-toc li {
                margin: 8px 0;
                padding-left: 0;
            }
            
            .table-ysxin.dynamic-toc li.toc-h3 {
                padding-left: 20px;
            }
            
            .table-ysxin.dynamic-toc li.toc-h4 {
                padding-left: 40px;
            }
            
            .table-ysxin.dynamic-toc a {
                color: #333;
                text-decoration: none;
                transition: color 0.3s ease;
            }
            
            .table-ysxin.dynamic-toc a:hover {
                color: #0073aa;
                text-decoration: underline;
            }
        ');
    }
}
add_action('wp_enqueue_scripts', 'enqueue_toc_styles');

/**
 * JavaScript for smooth scrolling (optional)
 */
function enqueue_toc_scripts() {
    if (is_single()) {
        wp_add_inline_script('jquery', '
            jQuery(document).ready(function($) {
                $(".table-ysxin.dynamic-toc a[href^=\'#\']").click(function(e) {
                    e.preventDefault();
                    var target = $(this.hash);
                    if (target.length) {
                        $("html, body").animate({
                            scrollTop: target.offset().top - 100
                        }, 800);
                    }
                });
            });
        ');
    }
}
add_action('wp_enqueue_scripts', 'enqueue_toc_scripts');
?>
×
创建自定义TOC

创建自定义TOC

<?php /** * Dynam...