*/ public static function extract_faq_items( string $content ): array { if ( '' === trim( $content ) || ! function_exists( 'parse_blocks' ) ) { return array(); } $blocks = parse_blocks( $content ); if ( ! is_array( $blocks ) ) { return array(); } $stack = $blocks; $out = array(); while ( ! empty( $stack ) ) { $block = array_shift( $stack ); $name = (string) ( $block['blockName'] ?? '' ); $attrs = (array) ( $block['attrs'] ?? array() ); // Yoast: one block per question. if ( 'yoast/faq-question' === $name ) { $q = trim( (string) ( $attrs['question'] ?? '' ) ); $a = trim( (string) ( $attrs['answer'] ?? '' ) ); if ( '' !== $q && '' !== $a ) { $out[] = array( 'question' => wp_strip_all_tags( $q ), 'answer' => wp_strip_all_tags( $a ), ); } } // Rank Math: questions list on container block. if ( 'rank-math/faq-block' === $name && ! empty( $attrs['questions'] ) && is_array( $attrs['questions'] ) ) { foreach ( $attrs['questions'] as $qa ) { if ( ! is_array( $qa ) ) { continue; } $q = trim( (string) ( $qa['title'] ?? '' ) ); $a = trim( (string) ( $qa['content'] ?? '' ) ); if ( '' !== $q && '' !== $a ) { $out[] = array( 'question' => wp_strip_all_tags( $q ), 'answer' => wp_strip_all_tags( $a ), ); } } } // Recurse into inner blocks. if ( ! empty( $block['innerBlocks'] ) && is_array( $block['innerBlocks'] ) ) { foreach ( $block['innerBlocks'] as $inner ) { $stack[] = $inner; } } } return $out; } /** * Extract HowTo steps from Yoast and Rank Math HowTo blocks. * * @param string $content Post content (raw, unmodified). * @return array */ public static function extract_howto_steps( string $content ): array { if ( '' === trim( $content ) || ! function_exists( 'parse_blocks' ) ) { return array(); } $blocks = parse_blocks( $content ); if ( ! is_array( $blocks ) ) { return array(); } $stack = $blocks; $out = array(); while ( ! empty( $stack ) ) { $block = array_shift( $stack ); $name = (string) ( $block['blockName'] ?? '' ); $attrs = (array) ( $block['attrs'] ?? array() ); // Yoast HowTo block: steps carry `text`. if ( 'yoast/how-to-block' === $name && ! empty( $attrs['steps'] ) && is_array( $attrs['steps'] ) ) { foreach ( $attrs['steps'] as $step ) { if ( ! is_array( $step ) ) { continue; } $text = trim( wp_strip_all_tags( (string) ( $step['text'] ?? '' ) ) ); $name_field = trim( wp_strip_all_tags( (string) ( $step['name'] ?? '' ) ) ); if ( '' !== $text || '' !== $name_field ) { $out[] = array( 'name' => '' !== $name_field ? $name_field : $text, 'text' => '' !== $text ? $text : $name_field, ); } } } // Rank Math HowTo block: steps carry `description` and `title`. if ( 'rank-math/howto-block' === $name && ! empty( $attrs['steps'] ) && is_array( $attrs['steps'] ) ) { foreach ( $attrs['steps'] as $step ) { if ( ! is_array( $step ) ) { continue; } $text = trim( wp_strip_all_tags( (string) ( $step['description'] ?? '' ) ) ); $name_field = trim( wp_strip_all_tags( (string) ( $step['title'] ?? '' ) ) ); if ( '' !== $text || '' !== $name_field ) { $out[] = array( 'name' => '' !== $name_field ? $name_field : $text, 'text' => '' !== $text ? $text : $name_field, ); } } } if ( ! empty( $block['innerBlocks'] ) && is_array( $block['innerBlocks'] ) ) { foreach ( $block['innerBlocks'] as $inner ) { $stack[] = $inner; } } } return $out; } }