@@ -349,54 +349,114 @@ function twenty_twenty_one_get_non_latin_css( $type = 'front-end' ) {
349349 );
350350}
351351
352- /**
353- * Prints the first instance of a block in the content, and then break away.
354- *
355- * @since Twenty Twenty-One 1.0
356- *
357- * @param string $block_name The full block type name, or a partial match.
358- * Example: `core/image`, `core-embed/*`.
359- * @param string|null $content The content to search in. Use null for get_the_content().
360- * @param int $instances How many instances of the block will be printed (max). Default 1.
361- * @return bool Returns true if a block was located & printed, otherwise false.
362- */
363- function twenty_twenty_one_print_first_instance_of_block ( $ block_name , $ content = null , $ instances = 1 ) {
364- $ blocks_content = '' ;
352+ if ( class_exists ( 'WP_Block_Processor ' ) ) :
353+ /**
354+ * Prints the first instance of a block in the content, and then break away.
355+ *
356+ * @since Twenty Twenty-One 1.0
357+ *
358+ * @param string $block_name The full block type name, or a partial match.
359+ * Example: `core/image`, `core-embed/*`.
360+ * @param string|null $content The content to search in. Use null for get_the_content().
361+ * @param int $instances How many instances of the block will be printed (max). Default 1.
362+ * @return bool Returns true if a block was located & printed, otherwise false.
363+ */
364+ function twenty_twenty_one_print_first_instance_of_block ( $ block_name , $ content = null , $ instances = 1 ) {
365+ $ blocks_content = '' ;
365366
366- if ( ! $ content ) {
367- $ content = get_the_content ();
368- }
367+ if ( ! $ content ) {
368+ $ content = get_the_content ();
369+ }
369370
370- $ processor = new WP_Block_Processor ( $ content );
371- $ instance_count = 0 ;
371+ $ processor = new WP_Block_Processor ( $ content );
372+ $ instance_count = 0 ;
372373
373- if ( str_ends_with ( $ block_name , '* ' ) ) {
374- // Scan for blocks whose block type matches the prefix.
375- $ prefix = rtrim ( $ block_name , '* ' );
374+ if ( str_ends_with ( $ block_name , '* ' ) ) {
375+ // Scan for blocks whose block type matches the prefix.
376+ $ prefix = rtrim ( $ block_name , '* ' );
376377
377- while ( $ instance_count < $ instances && $ processor ->next_block () ) {
378- $ matched_block_type = $ processor ->get_printable_block_type ();
379- if ( str_starts_with ( $ matched_block_type , $ prefix ) ) {
378+ while ( $ instance_count < $ instances && $ processor ->next_block () ) {
379+ $ matched_block_type = $ processor ->get_printable_block_type ();
380+ if ( str_starts_with ( $ matched_block_type , $ prefix ) ) {
381+ $ blocks_content .= render_block ( $ processor ->extract_full_block_and_advance () );
382+ ++$ instance_count ;
383+ }
384+ }
385+ } else {
386+ // Scan for blocks of the exact block type.
387+ while ( $ instance_count < $ instances && $ processor ->next_block ( $ block_name ) ) {
380388 $ blocks_content .= render_block ( $ processor ->extract_full_block_and_advance () );
381389 ++$ instance_count ;
382390 }
383391 }
384- } else {
385- // Scan for blocks of the exact block type.
386- while ( $ instance_count < $ instances && $ processor -> next_block ( $ block_name ) ) {
387- $ blocks_content .= render_block ( $ processor -> extract_full_block_and_advance () );
388- ++ $ instance_count ;
392+
393+ if ( $ blocks_content ) {
394+ /** This filter is documented in wp-includes/post-template.php */
395+ echo apply_filters ( ' the_content ' , $ blocks_content ); // phpcs:ignore WordPress.Security.EscapeOutput
396+ return true ;
389397 }
390- }
391398
392- if ( $ blocks_content ) {
393- /** This filter is documented in wp-includes/post-template.php */
394- echo apply_filters ( 'the_content ' , $ blocks_content ); // phpcs:ignore WordPress.Security.EscapeOutput
395- return true ;
399+ return false ;
396400 }
401+ else :
402+ /**
403+ * Fallback with legacy function for installations running WordPress <6.9.0.
404+ *
405+ * @ignore
406+ * @private
407+ */
408+ function twenty_twenty_one_print_first_instance_of_block ( $ block_name , $ content = null , $ instances = 1 ) {
409+ $ instances_count = 0 ;
410+ $ blocks_content = '' ;
397411
398- return false ;
399- }
412+ if ( ! $ content ) {
413+ $ content = get_the_content ();
414+ }
415+
416+ // Parse blocks in the content.
417+ $ blocks = parse_blocks ( $ content );
418+
419+ // Loop top-level blocks, releasing them from memory as soon as possible.
420+ while ( null !== ( $ block = array_shift ( $ blocks ) ) ) {
421+
422+ // Skip inter-block whitespace and other freeform non-block HTML.
423+ if ( ! isset ( $ block ['blockName ' ] ) ) {
424+ continue ;
425+ }
426+
427+ // Check if this the block matches the $block_name.
428+ $ is_matching_block = false ;
429+
430+ // If the block ends with *, try to match the first portion.
431+ if ( '* ' === $ block_name [-1 ] ) {
432+ $ is_matching_block = 0 === strpos ( $ block ['blockName ' ], rtrim ( $ block_name , '* ' ) );
433+ } else {
434+ $ is_matching_block = $ block_name === $ block ['blockName ' ];
435+ }
436+
437+ if ( $ is_matching_block ) {
438+ // Increment count.
439+ ++$ instances_count ;
440+
441+ // Add the block HTML.
442+ $ blocks_content .= render_block ( $ block );
443+
444+ // Break the loop if the $instances count was reached.
445+ if ( $ instances_count >= $ instances ) {
446+ break ;
447+ }
448+ }
449+ }
450+
451+ if ( $ blocks_content ) {
452+ /** This filter is documented in wp-includes/post-template.php */
453+ echo apply_filters ( 'the_content ' , $ blocks_content ); // phpcs:ignore WordPress.Security.EscapeOutput
454+ return true ;
455+ }
456+
457+ return false ;
458+ }
459+ endif ;
400460
401461/**
402462 * Retrieves protected post password form content.
0 commit comments