Files
WP-Multi-Wiki/includes/class-wmw-toc.php
2026-03-18 21:56:45 +01:00

69 lines
2.2 KiB
PHP

<?php
if ( ! defined( 'ABSPATH' ) ) exit;
class WMW_TOC {
/**
* Generate TOC and add anchor IDs to headings in content.
* Returns array: ['content' => ..., 'toc' => ...]
*/
public static function process( $content ) {
if ( empty( $content ) ) return array( 'content' => $content, 'toc' => '' );
$headings = array();
$counter = array();
// Add IDs to h2, h3, h4
$content = preg_replace_callback(
'/<(h[234])([^>]*)>(.*?)<\/h[234]>/si',
function( $matches ) use ( &$headings, &$counter ) {
$tag = $matches[1];
$attrs = $matches[2];
$text = wp_strip_all_tags( $matches[3] );
$slug = sanitize_title( $text );
// Make unique
if ( isset( $counter[ $slug ] ) ) {
$counter[ $slug ]++;
$slug .= '-' . $counter[ $slug ];
} else {
$counter[ $slug ] = 0;
}
$headings[] = array(
'level' => (int) substr( $tag, 1 ),
'id' => $slug,
'text' => $text,
);
return "<{$tag}{$attrs} id=\"{$slug}\">{$matches[3]}</{$tag}>";
},
$content
);
if ( empty( $headings ) || count( $headings ) < 2 ) {
return array( 'content' => $content, 'toc' => '' );
}
// Build TOC HTML
$toc = '<div class="wmw-toc">';
$toc .= '<div class="wmw-toc__title"><span>' . __( 'Inhalt', 'wp-multi-wiki' ) . '</span><button class="wmw-toc__toggle" aria-label="TOC ausklappen">▼</button></div>';
$toc .= '<ol class="wmw-toc__list">';
$prev_level = 2;
foreach ( $headings as $h ) {
if ( $h['level'] > $prev_level ) {
$toc .= '<ol class="wmw-toc__sub">';
} elseif ( $h['level'] < $prev_level ) {
$toc .= '</ol>';
}
$toc .= '<li><a href="#' . esc_attr( $h['id'] ) . '">' . esc_html( $h['text'] ) . '</a></li>';
$prev_level = $h['level'];
}
$toc .= '</ol></div>';
return array( 'content' => $content, 'toc' => $toc );
}
}