From e9f0d8a87479e771faab3cb799ab17f3a07de4a6 Mon Sep 17 00:00:00 2001 From: Dennis Snell Date: Wed, 13 Aug 2025 17:30:05 -0500 Subject: [PATCH 01/11] Refactor twentwentyone to use Block_Processor --- .../inc/template-functions.php | 46 +++++++------------ 1 file changed, 16 insertions(+), 30 deletions(-) diff --git a/src/wp-content/themes/twentytwentyone/inc/template-functions.php b/src/wp-content/themes/twentytwentyone/inc/template-functions.php index 689b1e22c9814..edb2d0e95624f 100644 --- a/src/wp-content/themes/twentytwentyone/inc/template-functions.php +++ b/src/wp-content/themes/twentytwentyone/inc/template-functions.php @@ -361,46 +361,32 @@ function twenty_twenty_one_get_non_latin_css( $type = 'front-end' ) { * @return bool Returns true if a block was located & printed, otherwise false. */ function twenty_twenty_one_print_first_instance_of_block( $block_name, $content = null, $instances = 1 ) { - $instances_count = 0; $blocks_content = ''; if ( ! $content ) { $content = get_the_content(); } - // Parse blocks in the content. - $blocks = parse_blocks( $content ); + $processor = new WP_Block_Processor( $content ); + $instance_count = 0; - // Loop blocks. - foreach ( $blocks as $block ) { + if ( str_ends_with( $block_name, '*' ) ) { + // Scan for blocks whose block type matches the prefix. + $prefix = rtrim( $block_name, '*' ); - // Confidence check. - if ( ! isset( $block['blockName'] ) ) { - continue; - } - - // Check if this the block matches the $block_name. - $is_matching_block = false; - - // If the block ends with *, try to match the first portion. - if ( '*' === $block_name[-1] ) { - $is_matching_block = 0 === strpos( $block['blockName'], rtrim( $block_name, '*' ) ); - } else { - $is_matching_block = $block_name === $block['blockName']; - } - - if ( $is_matching_block ) { - // Increment count. - ++$instances_count; - - // Add the block HTML. - $blocks_content .= render_block( $block ); - - // Break the loop if the $instances count was reached. - if ( $instances_count >= $instances ) { - break; + while ( $instance_count < $instances && $processor->next_block() ) { + $matched_block_type = $processor->get_printable_block_type(); + if ( str_starts_with( $matched_block_type, $prefix ) ) { + $blocks_content .= render_block( $processor->extract_full_block_and_advance() ); + ++$instance_count; } } + } else { + // Scan for blocks of the exact block type. + while ( $instance_count < $instances && $processor->next_block( $block_name ) ) { + $blocks_content .= render_block( $processor->extract_full_block_and_advance() ); + ++$instance_count; + } } if ( $blocks_content ) { From 67b1cf734d8234bdf33543d33780300ecebfde61 Mon Sep 17 00:00:00 2001 From: Dennis Snell Date: Wed, 7 Jan 2026 10:01:52 -0700 Subject: [PATCH 02/11] Re-introduce legacy function for environments pre-6.9.0. --- .../inc/template-functions.php | 132 +++++++++++++----- 1 file changed, 96 insertions(+), 36 deletions(-) diff --git a/src/wp-content/themes/twentytwentyone/inc/template-functions.php b/src/wp-content/themes/twentytwentyone/inc/template-functions.php index edb2d0e95624f..cad55cb7a33bc 100644 --- a/src/wp-content/themes/twentytwentyone/inc/template-functions.php +++ b/src/wp-content/themes/twentytwentyone/inc/template-functions.php @@ -349,54 +349,114 @@ function twenty_twenty_one_get_non_latin_css( $type = 'front-end' ) { ); } -/** - * Prints the first instance of a block in the content, and then break away. - * - * @since Twenty Twenty-One 1.0 - * - * @param string $block_name The full block type name, or a partial match. - * Example: `core/image`, `core-embed/*`. - * @param string|null $content The content to search in. Use null for get_the_content(). - * @param int $instances How many instances of the block will be printed (max). Default 1. - * @return bool Returns true if a block was located & printed, otherwise false. - */ -function twenty_twenty_one_print_first_instance_of_block( $block_name, $content = null, $instances = 1 ) { - $blocks_content = ''; +if ( class_exists( 'WP_Block_Processor' ) ) : + /** + * Prints the first instance of a block in the content, and then break away. + * + * @since Twenty Twenty-One 1.0 + * + * @param string $block_name The full block type name, or a partial match. + * Example: `core/image`, `core-embed/*`. + * @param string|null $content The content to search in. Use null for get_the_content(). + * @param int $instances How many instances of the block will be printed (max). Default 1. + * @return bool Returns true if a block was located & printed, otherwise false. + */ + function twenty_twenty_one_print_first_instance_of_block( $block_name, $content = null, $instances = 1 ) { + $blocks_content = ''; - if ( ! $content ) { - $content = get_the_content(); - } + if ( ! $content ) { + $content = get_the_content(); + } - $processor = new WP_Block_Processor( $content ); - $instance_count = 0; + $processor = new WP_Block_Processor( $content ); + $instance_count = 0; - if ( str_ends_with( $block_name, '*' ) ) { - // Scan for blocks whose block type matches the prefix. - $prefix = rtrim( $block_name, '*' ); + if ( str_ends_with( $block_name, '*' ) ) { + // Scan for blocks whose block type matches the prefix. + $prefix = rtrim( $block_name, '*' ); - while ( $instance_count < $instances && $processor->next_block() ) { - $matched_block_type = $processor->get_printable_block_type(); - if ( str_starts_with( $matched_block_type, $prefix ) ) { + while ( $instance_count < $instances && $processor->next_block() ) { + $matched_block_type = $processor->get_printable_block_type(); + if ( str_starts_with( $matched_block_type, $prefix ) ) { + $blocks_content .= render_block( $processor->extract_full_block_and_advance() ); + ++$instance_count; + } + } + } else { + // Scan for blocks of the exact block type. + while ( $instance_count < $instances && $processor->next_block( $block_name ) ) { $blocks_content .= render_block( $processor->extract_full_block_and_advance() ); ++$instance_count; } } - } else { - // Scan for blocks of the exact block type. - while ( $instance_count < $instances && $processor->next_block( $block_name ) ) { - $blocks_content .= render_block( $processor->extract_full_block_and_advance() ); - ++$instance_count; + + if ( $blocks_content ) { + /** This filter is documented in wp-includes/post-template.php */ + echo apply_filters( 'the_content', $blocks_content ); // phpcs:ignore WordPress.Security.EscapeOutput + return true; } - } - if ( $blocks_content ) { - /** This filter is documented in wp-includes/post-template.php */ - echo apply_filters( 'the_content', $blocks_content ); // phpcs:ignore WordPress.Security.EscapeOutput - return true; + return false; } +else : + /** + * Fallback with legacy function for installations running WordPress <6.9.0. + * + * @ignore + * @private + */ + function twenty_twenty_one_print_first_instance_of_block( $block_name, $content = null, $instances = 1 ) { + $instances_count = 0; + $blocks_content = ''; - return false; -} + if ( ! $content ) { + $content = get_the_content(); + } + + // Parse blocks in the content. + $blocks = parse_blocks( $content ); + + // Loop top-level blocks, releasing them from memory as soon as possible. + while ( null !== ( $block = array_shift( $blocks ) ) ) { + + // Skip inter-block whitespace and other freeform non-block HTML. + if ( ! isset( $block['blockName'] ) ) { + continue; + } + + // Check if this the block matches the $block_name. + $is_matching_block = false; + + // If the block ends with *, try to match the first portion. + if ( '*' === $block_name[-1] ) { + $is_matching_block = 0 === strpos( $block['blockName'], rtrim( $block_name, '*' ) ); + } else { + $is_matching_block = $block_name === $block['blockName']; + } + + if ( $is_matching_block ) { + // Increment count. + ++$instances_count; + + // Add the block HTML. + $blocks_content .= render_block( $block ); + + // Break the loop if the $instances count was reached. + if ( $instances_count >= $instances ) { + break; + } + } + } + + if ( $blocks_content ) { + /** This filter is documented in wp-includes/post-template.php */ + echo apply_filters( 'the_content', $blocks_content ); // phpcs:ignore WordPress.Security.EscapeOutput + return true; + } + + return false; + } +endif; /** * Retrieves protected post password form content. From 9015395c36c78839617a2126bc739c68d5caa4d2 Mon Sep 17 00:00:00 2001 From: Dennis Snell Date: Wed, 7 Jan 2026 10:29:08 -0700 Subject: [PATCH 03/11] Adjust Block Processor logic to only scan top-level blocks. --- .../inc/template-functions.php | 39 ++++++++++++------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/src/wp-content/themes/twentytwentyone/inc/template-functions.php b/src/wp-content/themes/twentytwentyone/inc/template-functions.php index cad55cb7a33bc..12d17a403646a 100644 --- a/src/wp-content/themes/twentytwentyone/inc/template-functions.php +++ b/src/wp-content/themes/twentytwentyone/inc/template-functions.php @@ -349,6 +349,11 @@ function twenty_twenty_one_get_non_latin_css( $type = 'front-end' ) { ); } +/** + * Remove the legacy fallback once the theme’s minimum required version is 6.9.0 or greater. + * + * @see ../style.css “Requires at least: VERSION_NUMBER” + */ if ( class_exists( 'WP_Block_Processor' ) ) : /** * Prints the first instance of a block in the content, and then break away. @@ -371,20 +376,23 @@ function twenty_twenty_one_print_first_instance_of_block( $block_name, $content $processor = new WP_Block_Processor( $content ); $instance_count = 0; - if ( str_ends_with( $block_name, '*' ) ) { - // Scan for blocks whose block type matches the prefix. - $prefix = rtrim( $block_name, '*' ); - - while ( $instance_count < $instances && $processor->next_block() ) { - $matched_block_type = $processor->get_printable_block_type(); - if ( str_starts_with( $matched_block_type, $prefix ) ) { - $blocks_content .= render_block( $processor->extract_full_block_and_advance() ); - ++$instance_count; - } - } - } else { - // Scan for blocks of the exact block type. - while ( $instance_count < $instances && $processor->next_block( $block_name ) ) { + // Scan for blocks whose block type matches the prefix. + $prefix = rtrim( $block_name, '*' ); + $match_fully = $prefix === $block_name; + + // Loop over top-level blocks. + while ( $processor->next_block() && $instance_count < $instances ) { + if ( + 1 === $processor->get_depth() && + /* + * Prefix matches with a wildcard require printing the block name, + * while full block-type matching can be delegated to the processor. + * In each case, the condition only holds when the match is successful. + */ + $match_fully + ? $processor->is_block_type( $block_name ) + : str_starts_with( $processor->get_printable_block_type(), $prefix ) + ) { $blocks_content .= render_block( $processor->extract_full_block_and_advance() ); ++$instance_count; } @@ -402,6 +410,9 @@ function twenty_twenty_one_print_first_instance_of_block( $block_name, $content /** * Fallback with legacy function for installations running WordPress <6.9.0. * + * @todo Remove once this theme’s minimum support version is 6.9.0 or greater. + * @see ../style.css “Requires at least: VERSION_NUMBER” + * * @ignore * @private */ From 9d100de6fa575b9a7289ebfb2145cc80ca032680 Mon Sep 17 00:00:00 2001 From: Dennis Snell Date: Wed, 7 Jan 2026 15:13:22 -0700 Subject: [PATCH 04/11] Recombine separate functions, harmonize logic. --- .../inc/template-functions.php | 123 ++++++------------ 1 file changed, 38 insertions(+), 85 deletions(-) diff --git a/src/wp-content/themes/twentytwentyone/inc/template-functions.php b/src/wp-content/themes/twentytwentyone/inc/template-functions.php index 12d17a403646a..24914cd3a3f8e 100644 --- a/src/wp-content/themes/twentytwentyone/inc/template-functions.php +++ b/src/wp-content/themes/twentytwentyone/inc/template-functions.php @@ -350,38 +350,32 @@ function twenty_twenty_one_get_non_latin_css( $type = 'front-end' ) { } /** - * Remove the legacy fallback once the theme’s minimum required version is 6.9.0 or greater. + * Prints the first instance of a block in the content, and then break away. * - * @see ../style.css “Requires at least: VERSION_NUMBER” + * @since Twenty Twenty-One 1.0 + * + * @param string $block_name The full block type name, or a partial match. + * Example: `core/image`, `core-embed/*`. + * @param string|null $content The content to search in. Use null for get_the_content(). + * @param int $instances How many instances of the block will be printed (max). Default 1. + * @return bool Returns true if a block was located & printed, otherwise false. */ -if ( class_exists( 'WP_Block_Processor' ) ) : - /** - * Prints the first instance of a block in the content, and then break away. - * - * @since Twenty Twenty-One 1.0 - * - * @param string $block_name The full block type name, or a partial match. - * Example: `core/image`, `core-embed/*`. - * @param string|null $content The content to search in. Use null for get_the_content(). - * @param int $instances How many instances of the block will be printed (max). Default 1. - * @return bool Returns true if a block was located & printed, otherwise false. - */ - function twenty_twenty_one_print_first_instance_of_block( $block_name, $content = null, $instances = 1 ) { - $blocks_content = ''; - - if ( ! $content ) { - $content = get_the_content(); - } - - $processor = new WP_Block_Processor( $content ); - $instance_count = 0; +function twenty_twenty_one_print_first_instance_of_block( $block_name, $content = null, $instances = 1 ) { + // Scan for blocks whose block type matches the prefix, if provided a wildcard. + $prefix = rtrim( $block_name, '*' ); + $match_fully = $prefix === $block_name; + $blocks_content = ''; + $instance_count = 0; + + if ( ! $content ) { + $content = get_the_content(); + } - // Scan for blocks whose block type matches the prefix. - $prefix = rtrim( $block_name, '*' ); - $match_fully = $prefix === $block_name; + // Loop over top-level blocks. + if ( class_exists( '\WP_Block_Processor' ) ) { + $processor = new WP_Block_Processor( $content ); - // Loop over top-level blocks. - while ( $processor->next_block() && $instance_count < $instances ) { + while ( $instance_count < $instances && $processor->next_block() ) { if ( 1 === $processor->get_depth() && /* @@ -397,77 +391,36 @@ function twenty_twenty_one_print_first_instance_of_block( $block_name, $content ++$instance_count; } } - - if ( $blocks_content ) { - /** This filter is documented in wp-includes/post-template.php */ - echo apply_filters( 'the_content', $blocks_content ); // phpcs:ignore WordPress.Security.EscapeOutput - return true; - } - - return false; - } -else : - /** - * Fallback with legacy function for installations running WordPress <6.9.0. - * - * @todo Remove once this theme’s minimum support version is 6.9.0 or greater. - * @see ../style.css “Requires at least: VERSION_NUMBER” - * - * @ignore - * @private - */ - function twenty_twenty_one_print_first_instance_of_block( $block_name, $content = null, $instances = 1 ) { - $instances_count = 0; - $blocks_content = ''; - - if ( ! $content ) { - $content = get_the_content(); - } - + } else { // Parse blocks in the content. $blocks = parse_blocks( $content ); // Loop top-level blocks, releasing them from memory as soon as possible. - while ( null !== ( $block = array_shift( $blocks ) ) ) { - + while ( $instance_count < $instances && null !== ( $block = array_shift( $blocks ) ) ) { // Skip inter-block whitespace and other freeform non-block HTML. if ( ! isset( $block['blockName'] ) ) { continue; } - // Check if this the block matches the $block_name. - $is_matching_block = false; - - // If the block ends with *, try to match the first portion. - if ( '*' === $block_name[-1] ) { - $is_matching_block = 0 === strpos( $block['blockName'], rtrim( $block_name, '*' ) ); - } else { - $is_matching_block = $block_name === $block['blockName']; - } - - if ( $is_matching_block ) { - // Increment count. - ++$instances_count; - - // Add the block HTML. + if ( + $match_fully + ? $block_name === $block['blockName'] + : str_starts_with( $block['blockName'], $prefix ) + ) { $blocks_content .= render_block( $block ); - - // Break the loop if the $instances count was reached. - if ( $instances_count >= $instances ) { - break; - } + ++$instance_count; } } + } - if ( $blocks_content ) { - /** This filter is documented in wp-includes/post-template.php */ - echo apply_filters( 'the_content', $blocks_content ); // phpcs:ignore WordPress.Security.EscapeOutput - return true; - } - - return false; + if ( $blocks_content ) { + /** This filter is documented in wp-includes/post-template.php */ + echo apply_filters( 'the_content', $blocks_content ); // phpcs:ignore WordPress.Security.EscapeOutput + return true; } -endif; + + return false; +} /** * Retrieves protected post password form content. From 35019d2c8b3c1a6500f1905a82a071f21edcc0d6 Mon Sep 17 00:00:00 2001 From: Dennis Snell Date: Wed, 7 Jan 2026 15:28:18 -0700 Subject: [PATCH 05/11] The freeform-check is redundant, already handled by the matching logic. --- .../themes/twentytwentyone/inc/template-functions.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/wp-content/themes/twentytwentyone/inc/template-functions.php b/src/wp-content/themes/twentytwentyone/inc/template-functions.php index 24914cd3a3f8e..86d87aba8aea0 100644 --- a/src/wp-content/themes/twentytwentyone/inc/template-functions.php +++ b/src/wp-content/themes/twentytwentyone/inc/template-functions.php @@ -397,15 +397,10 @@ function twenty_twenty_one_print_first_instance_of_block( $block_name, $content // Loop top-level blocks, releasing them from memory as soon as possible. while ( $instance_count < $instances && null !== ( $block = array_shift( $blocks ) ) ) { - // Skip inter-block whitespace and other freeform non-block HTML. - if ( ! isset( $block['blockName'] ) ) { - continue; - } - if ( $match_fully ? $block_name === $block['blockName'] - : str_starts_with( $block['blockName'], $prefix ) + : str_starts_with( $block['blockName'] ?? '', $prefix ) ) { $blocks_content .= render_block( $block ); ++$instance_count; From 99968c464e5f8236c6854b11a59df35f3f671d0c Mon Sep 17 00:00:00 2001 From: Dennis Snell Date: Mon, 12 Jan 2026 22:58:17 -0700 Subject: [PATCH 06/11] Remove `str_starts_with()` and fix precedence defect. --- .../themes/twentytwentyone/inc/template-functions.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/wp-content/themes/twentytwentyone/inc/template-functions.php b/src/wp-content/themes/twentytwentyone/inc/template-functions.php index 86d87aba8aea0..b3407d4aa558d 100644 --- a/src/wp-content/themes/twentytwentyone/inc/template-functions.php +++ b/src/wp-content/themes/twentytwentyone/inc/template-functions.php @@ -363,6 +363,7 @@ function twenty_twenty_one_get_non_latin_css( $type = 'front-end' ) { function twenty_twenty_one_print_first_instance_of_block( $block_name, $content = null, $instances = 1 ) { // Scan for blocks whose block type matches the prefix, if provided a wildcard. $prefix = rtrim( $block_name, '*' ); + $prefix_length = strlen( $prefix ); $match_fully = $prefix === $block_name; $blocks_content = ''; $instance_count = 0; @@ -376,8 +377,11 @@ function twenty_twenty_one_print_first_instance_of_block( $block_name, $content $processor = new WP_Block_Processor( $content ); while ( $instance_count < $instances && $processor->next_block() ) { + if ( 1 !== $processor->get_depth() ) { + continue; + } + if ( - 1 === $processor->get_depth() && /* * Prefix matches with a wildcard require printing the block name, * while full block-type matching can be delegated to the processor. @@ -385,7 +389,7 @@ function twenty_twenty_one_print_first_instance_of_block( $block_name, $content */ $match_fully ? $processor->is_block_type( $block_name ) - : str_starts_with( $processor->get_printable_block_type(), $prefix ) + : 0 === substr_compare( $processor->get_printable_block_type(), $prefix, 0, $prefix_length ) ) { $blocks_content .= render_block( $processor->extract_full_block_and_advance() ); ++$instance_count; From 52e0dd3aaa08d7e53b5bb2bee5836ac34ed2c678 Mon Sep 17 00:00:00 2001 From: Dennis Snell Date: Mon, 12 Jan 2026 23:05:58 -0700 Subject: [PATCH 07/11] Revert legacy code changes, bring back str_starts_with --- .../inc/template-functions.php | 49 +++++++++++++------ 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/src/wp-content/themes/twentytwentyone/inc/template-functions.php b/src/wp-content/themes/twentytwentyone/inc/template-functions.php index b3407d4aa558d..899e988c31e21 100644 --- a/src/wp-content/themes/twentytwentyone/inc/template-functions.php +++ b/src/wp-content/themes/twentytwentyone/inc/template-functions.php @@ -361,10 +361,6 @@ function twenty_twenty_one_get_non_latin_css( $type = 'front-end' ) { * @return bool Returns true if a block was located & printed, otherwise false. */ function twenty_twenty_one_print_first_instance_of_block( $block_name, $content = null, $instances = 1 ) { - // Scan for blocks whose block type matches the prefix, if provided a wildcard. - $prefix = rtrim( $block_name, '*' ); - $prefix_length = strlen( $prefix ); - $match_fully = $prefix === $block_name; $blocks_content = ''; $instance_count = 0; @@ -373,8 +369,11 @@ function twenty_twenty_one_print_first_instance_of_block( $block_name, $content } // Loop over top-level blocks. - if ( class_exists( '\WP_Block_Processor' ) ) { - $processor = new WP_Block_Processor( $content ); + if ( class_exists( '\WP_Block_Processor' ) && function_exists( '\str_starts_with' ) ) { + // Scan for blocks whose block type matches the prefix, if provided a wildcard. + $prefix = rtrim( $block_name, '*' ); + $match_fully = $prefix === $block_name; + $processor = new WP_Block_Processor( $content ); while ( $instance_count < $instances && $processor->next_block() ) { if ( 1 !== $processor->get_depth() ) { @@ -389,7 +388,7 @@ function twenty_twenty_one_print_first_instance_of_block( $block_name, $content */ $match_fully ? $processor->is_block_type( $block_name ) - : 0 === substr_compare( $processor->get_printable_block_type(), $prefix, 0, $prefix_length ) + : str_starts_with( $processor->get_printable_block_type(), $prefix ) ) { $blocks_content .= render_block( $processor->extract_full_block_and_advance() ); ++$instance_count; @@ -399,15 +398,35 @@ function twenty_twenty_one_print_first_instance_of_block( $block_name, $content // Parse blocks in the content. $blocks = parse_blocks( $content ); - // Loop top-level blocks, releasing them from memory as soon as possible. - while ( $instance_count < $instances && null !== ( $block = array_shift( $blocks ) ) ) { - if ( - $match_fully - ? $block_name === $block['blockName'] - : str_starts_with( $block['blockName'] ?? '', $prefix ) - ) { - $blocks_content .= render_block( $block ); + // Loop blocks. + foreach ( $blocks as $block ) { + + // Confidence check. + if ( ! isset( $block['blockName'] ) ) { + continue; + } + + // Check if this the block matches the $block_name. + $is_matching_block = false; + + // If the block ends with *, try to match the first portion. + if ( '*' === $block_name[-1] ) { + $is_matching_block = 0 === strpos( $block['blockName'], rtrim( $block_name, '*' ) ); + } else { + $is_matching_block = $block_name === $block['blockName']; + } + + if ( $is_matching_block ) { + // Increment count. ++$instance_count; + + // Add the block HTML. + $blocks_content .= render_block( $block ); + + // Break the loop if the $instances count was reached. + if ( $instance_count >= $instances ) { + break; + } } } } From 3216ca17d83c05efb5d7d2ca35fa761b3c840023 Mon Sep 17 00:00:00 2001 From: Dennis Snell Date: Mon, 12 Jan 2026 23:08:05 -0700 Subject: [PATCH 08/11] Minimize diff by undoing unnecessary change --- .../themes/twentytwentyone/inc/template-functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-content/themes/twentytwentyone/inc/template-functions.php b/src/wp-content/themes/twentytwentyone/inc/template-functions.php index 899e988c31e21..22b22777fcae3 100644 --- a/src/wp-content/themes/twentytwentyone/inc/template-functions.php +++ b/src/wp-content/themes/twentytwentyone/inc/template-functions.php @@ -361,8 +361,8 @@ function twenty_twenty_one_get_non_latin_css( $type = 'front-end' ) { * @return bool Returns true if a block was located & printed, otherwise false. */ function twenty_twenty_one_print_first_instance_of_block( $block_name, $content = null, $instances = 1 ) { - $blocks_content = ''; $instance_count = 0; + $blocks_content = ''; if ( ! $content ) { $content = get_the_content(); From 26aebaae1a21d7226a42a49ea96edcf7cdb8a7df Mon Sep 17 00:00:00 2001 From: Dennis Snell Date: Mon, 12 Jan 2026 23:09:00 -0700 Subject: [PATCH 09/11] Undo rename --- .../themes/twentytwentyone/inc/template-functions.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/wp-content/themes/twentytwentyone/inc/template-functions.php b/src/wp-content/themes/twentytwentyone/inc/template-functions.php index 22b22777fcae3..dac1815bc35bf 100644 --- a/src/wp-content/themes/twentytwentyone/inc/template-functions.php +++ b/src/wp-content/themes/twentytwentyone/inc/template-functions.php @@ -361,7 +361,7 @@ function twenty_twenty_one_get_non_latin_css( $type = 'front-end' ) { * @return bool Returns true if a block was located & printed, otherwise false. */ function twenty_twenty_one_print_first_instance_of_block( $block_name, $content = null, $instances = 1 ) { - $instance_count = 0; + $instances_count = 0; $blocks_content = ''; if ( ! $content ) { @@ -375,7 +375,7 @@ function twenty_twenty_one_print_first_instance_of_block( $block_name, $content $match_fully = $prefix === $block_name; $processor = new WP_Block_Processor( $content ); - while ( $instance_count < $instances && $processor->next_block() ) { + while ( $instances_count < $instances && $processor->next_block() ) { if ( 1 !== $processor->get_depth() ) { continue; } @@ -391,7 +391,7 @@ function twenty_twenty_one_print_first_instance_of_block( $block_name, $content : str_starts_with( $processor->get_printable_block_type(), $prefix ) ) { $blocks_content .= render_block( $processor->extract_full_block_and_advance() ); - ++$instance_count; + ++$instances_count; } } } else { @@ -418,13 +418,13 @@ function twenty_twenty_one_print_first_instance_of_block( $block_name, $content if ( $is_matching_block ) { // Increment count. - ++$instance_count; + ++$instances_count; // Add the block HTML. $blocks_content .= render_block( $block ); // Break the loop if the $instances count was reached. - if ( $instance_count >= $instances ) { + if ( $instances_count >= $instances ) { break; } } From cfbff7fcf3cb1413a384a409a90211393e316dc7 Mon Sep 17 00:00:00 2001 From: Dennis Snell Date: Mon, 12 Jan 2026 23:09:47 -0700 Subject: [PATCH 10/11] wawawawa WPCS so much extra work --- .../themes/twentytwentyone/inc/template-functions.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/wp-content/themes/twentytwentyone/inc/template-functions.php b/src/wp-content/themes/twentytwentyone/inc/template-functions.php index dac1815bc35bf..3d5e4ee6b4bf5 100644 --- a/src/wp-content/themes/twentytwentyone/inc/template-functions.php +++ b/src/wp-content/themes/twentytwentyone/inc/template-functions.php @@ -371,9 +371,9 @@ function twenty_twenty_one_print_first_instance_of_block( $block_name, $content // Loop over top-level blocks. if ( class_exists( '\WP_Block_Processor' ) && function_exists( '\str_starts_with' ) ) { // Scan for blocks whose block type matches the prefix, if provided a wildcard. - $prefix = rtrim( $block_name, '*' ); - $match_fully = $prefix === $block_name; - $processor = new WP_Block_Processor( $content ); + $prefix = rtrim( $block_name, '*' ); + $match_fully = $prefix === $block_name; + $processor = new WP_Block_Processor( $content ); while ( $instances_count < $instances && $processor->next_block() ) { if ( 1 !== $processor->get_depth() ) { From 737b12f5191eaede079eb617f860b67a773f6999 Mon Sep 17 00:00:00 2001 From: Dennis Snell Date: Mon, 12 Jan 2026 23:12:52 -0700 Subject: [PATCH 11/11] By reusing match-text/prefix PHP can release $block_name earlier. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit this won’t matter, but it’s easy to add now --- .../themes/twentytwentyone/inc/template-functions.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wp-content/themes/twentytwentyone/inc/template-functions.php b/src/wp-content/themes/twentytwentyone/inc/template-functions.php index 3d5e4ee6b4bf5..74fd5939ec023 100644 --- a/src/wp-content/themes/twentytwentyone/inc/template-functions.php +++ b/src/wp-content/themes/twentytwentyone/inc/template-functions.php @@ -371,8 +371,8 @@ function twenty_twenty_one_print_first_instance_of_block( $block_name, $content // Loop over top-level blocks. if ( class_exists( '\WP_Block_Processor' ) && function_exists( '\str_starts_with' ) ) { // Scan for blocks whose block type matches the prefix, if provided a wildcard. - $prefix = rtrim( $block_name, '*' ); - $match_fully = $prefix === $block_name; + $match_text = rtrim( $block_name, '*' ); + $match_fully = $match_text === $block_name; $processor = new WP_Block_Processor( $content ); while ( $instances_count < $instances && $processor->next_block() ) { @@ -387,8 +387,8 @@ function twenty_twenty_one_print_first_instance_of_block( $block_name, $content * In each case, the condition only holds when the match is successful. */ $match_fully - ? $processor->is_block_type( $block_name ) - : str_starts_with( $processor->get_printable_block_type(), $prefix ) + ? $processor->is_block_type( $match_text ) + : str_starts_with( $processor->get_printable_block_type(), $match_text ) ) { $blocks_content .= render_block( $processor->extract_full_block_and_advance() ); ++$instances_count;