33 * Plugin Name: SimpleTOC - Table of Contents Block
44 * Plugin URI: https://marc.tv/simpletoc-wordpress-inhaltsverzeichnis-plugin-gutenberg/
55 * Description: SEO-friendly Table of Contents Gutenberg block. No JavaScript or CSS by default.
6- * Version: 7.0.3
6+ * Version: 7.0.4
77 * Author: Marc Tönsing
88 * Author URI: https://toensing.com
99 * Text Domain: simpletoc
@@ -221,8 +221,8 @@ function add_ids_to_blocks_recursive( $blocks ) {
221221
222222 foreach ( $ blocks as &$ block ) {
223223 if ( isset ( $ block ['blockName ' ] ) && in_array ( $ block ['blockName ' ], $ supported_blocks , true ) && isset ( $ block ['innerHTML ' ] ) && isset ( $ block ['innerContent ' ] ) && isset ( $ block ['innerContent ' ][0 ] ) ) {
224- $ block ['innerHTML ' ] = add_anchor_attribute ( $ block ['innerHTML ' ], $ inner_html_id_instance );
225- $ block ['innerContent ' ][0 ] = add_anchor_attribute ( $ block ['innerContent ' ][0 ], $ inner_content_id_instance );
224+ $ block ['innerHTML ' ] = add_anchor_attribute ( $ block ['innerHTML ' ], $ inner_html_id_instance, $ block );
225+ $ block ['innerContent ' ][0 ] = add_anchor_attribute ( $ block ['innerContent ' ][0 ], $ inner_content_id_instance, $ block );
226226 } elseif ( isset ( $ block ['attrs ' ]['ref ' ] ) ) { // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedElseif
227227 // search in reusable blocks (this is not finished because I ran out of ideas.)
228228 // $reusable_block_id = $block['attrs']['ref'];
@@ -430,6 +430,7 @@ function filter_headings_recursive( $blocks ) {
430430 if ( isset ( $ blocks ['blockName ' ] ) && in_array ( $ blocks ['blockName ' ], $ supported_third_party_blocks , true ) && 'core/heading ' !== $ inner_block ) {
431431 // make sure it's a headline.
432432 if ( preg_match ( '/(<h1|<h2|<h3|<h4|<h5|<h6)/i ' , $ inner_block ) ) {
433+ $ inner_block = simpletoc_maybe_replace_generateblocks_dynamic_tags ( $ inner_block , $ blocks );
433434 $ arr [] = $ inner_block ;
434435 }
435436 }
@@ -439,6 +440,38 @@ function filter_headings_recursive( $blocks ) {
439440 return $ arr ;
440441}
441442
443+ /**
444+ * Replaces GenerateBlocks dynamic tags in heading HTML before SimpleTOC uses it in the TOC.
445+ *
446+ * @param string $html The heading HTML.
447+ * @param array $block The parsed block data.
448+ * @return string The heading HTML with GenerateBlocks dynamic tags resolved when available.
449+ */
450+ function simpletoc_maybe_replace_generateblocks_dynamic_tags ( $ html , $ block ) {
451+ if ( ! class_exists ( '\GenerateBlocks_Register_Dynamic_Tag ' ) || false === strpos ( $ html , '{{ ' ) ) {
452+ return $ html ;
453+ }
454+
455+ return \GenerateBlocks_Register_Dynamic_Tag::replace_tags ( $ html , $ block , null );
456+ }
457+
458+ /**
459+ * Gets heading HTML used for anchor generation.
460+ *
461+ * @param string $html The original heading HTML.
462+ * @param array $block The parsed block data.
463+ * @return string The heading HTML to use for anchor generation.
464+ */
465+ function simpletoc_get_heading_html_for_anchor ( $ html , $ block ) {
466+ $ heading_html = simpletoc_maybe_replace_generateblocks_dynamic_tags ( $ html , $ block );
467+
468+ if ( '' === trim ( wp_strip_all_tags ( $ heading_html ) ) ) {
469+ return $ html ;
470+ }
471+
472+ return $ heading_html ;
473+ }
474+
442475/**
443476 * Sanitizes a string to be used as an anchor attribute in HTML by removing punctuation, non-breaking spaces, umlauts, and accents,
444477 * and replacing whitespace and other characters with dashes.
@@ -483,9 +516,10 @@ function simpletoc_plugin_meta( $links, $file ) {
483516 *
484517 * @param string $html The HTML content to modify.
485518 * @param SimpleTOC_Headline_Ids $headline_class_instance The instance of the SimpleTOC_Headline_Ids class.
519+ * @param array $block The parsed block data.
486520 * @return string The modified HTML content with ID attributes added to the Heading tags
487521 */
488- function add_anchor_attribute ( $ html , $ headline_class_instance = null ) {
522+ function add_anchor_attribute ( $ html , $ headline_class_instance = null , $ block = array () ) {
489523
490524 // remove non-breaking space entites from input HTML.
491525 $ html_wo_nbs = str_replace ( ' ' , ' ' , $ html );
@@ -495,6 +529,36 @@ function add_anchor_attribute( $html, $headline_class_instance = null ) {
495529 return $ html ;
496530 }
497531
532+ if ( ! class_exists ( '\WP_HTML_Tag_Processor ' ) && defined ( 'ABSPATH ' ) && defined ( 'WPINC ' ) ) {
533+ $ html_tag_processor_file = ABSPATH . WPINC . '/html-api/class-wp-html-tag-processor.php ' ;
534+
535+ if ( file_exists ( $ html_tag_processor_file ) ) {
536+ require_once $ html_tag_processor_file ;
537+ }
538+ }
539+
540+ if ( class_exists ( '\WP_HTML_Tag_Processor ' ) ) {
541+ $ processor = new \WP_HTML_Tag_Processor ( $ html_wo_nbs );
542+
543+ while ( $ processor ->next_tag () ) {
544+ if ( ! in_array ( $ processor ->get_tag (), array ( 'H1 ' , 'H2 ' , 'H3 ' , 'H4 ' , 'H5 ' , 'H6 ' ), true ) ) {
545+ continue ;
546+ }
547+
548+ // If tag already has an attribute "id" defined, no need for creating a new one.
549+ if ( ! empty ( $ processor ->get_attribute ( 'id ' ) ) ) {
550+ continue ;
551+ }
552+
553+ $ heading_html = simpletoc_get_heading_html_for_anchor ( $ html , $ block );
554+ $ heading_text = trim ( wp_strip_all_tags ( $ heading_html ) );
555+ $ anchor = $ headline_class_instance ->get_headline_anchor ( $ heading_text );
556+ $ processor ->set_attribute ( 'id ' , $ anchor );
557+ }
558+
559+ return $ processor ->get_updated_html ();
560+ }
561+
498562 libxml_use_internal_errors ( true );
499563 $ dom = new \DOMDocument ();
500564 try {
@@ -514,7 +578,8 @@ function add_anchor_attribute( $html, $headline_class_instance = null ) {
514578 continue ;
515579 }
516580 // Set id attribute.
517- $ heading_text = trim ( wp_strip_all_tags ( $ html ) );
581+ $ heading_html = simpletoc_get_heading_html_for_anchor ( $ html , $ block );
582+ $ heading_text = trim ( wp_strip_all_tags ( $ heading_html ) );
518583 $ anchor = $ headline_class_instance ->get_headline_anchor ( $ heading_text );
519584 $ tag ->setAttribute ( 'id ' , $ anchor );
520585 }
0 commit comments