WordPress.org

WordPress Developer Blog

Snippet: Schema.org microdata for Accordion block FAQs

Snippet: Schema.org microdata for Accordion block FAQs

In Styling accordions in WordPress 6.9, I walked you through styling a FAQs page with the WordPress 6.9 Accordion block. One of the requests from that tutorial was the ability to define Schema.org microdata for the HTML output so that search engines can understand and index the FAQ content. And this is entirely possible using the WP_HTML_Tag_Processor class in WordPress.

To make this technique work, add an Accordion block to the editor, and give it a class of is-faqs via the Advanced Additional CSS Class(es) field in the block inspector panel. Then, add this code to your theme’s functions.php file or a custom plugin:

add_filter( 'render_block_core/accordion', 'projectslug_render_accordion_faqs' );

function projectslug_render_accordion_faqs( $content ): string
{
	$processor = new WP_HTML_Tag_Processor( $content );

	// Bail early if there's no Accordion block with the `.is-faqs` class.
	if (
		! $processor->next_tag( [ 'class_name' => 'wp-block-accordion' ] )
		|| ! $processor->has_class( 'is-faqs' )
	) {
		return $processor->get_updated_html();
	}

	// Add attributes to wrapping accordion block.
	$processor->set_attribute( 'itemscope', true );
	$processor->set_attribute( 'itemtype', 'https://schema.org/FAQPage' );

	// Loop through accordion items and add attributes.
	while ( $processor->next_tag( [ 'class_name' => 'wp-block-accordion-item' ] ) ) {
		$processor->set_attribute( 'itemscope', true );
		$processor->set_attribute( 'itemprop', 'mainEntity' );
		$processor->set_attribute( 'itemtype', 'https://schema.org/Question' );

		// Add attributes to the title element.
		if ( $processor->next_tag( [ 'class_name' => 'wp-block-accordion-heading__toggle-title' ] ) ) {
			$processor->set_attribute( 'itemprop', 'name' );
		}

		// Add attributes to the panel.
		if ( $processor->next_tag( [ 'class_name' => 'wp-block-accordion-panel' ] ) ) {
			$processor->set_attribute( 'itemscope', true );
			$processor->set_attribute( 'itemprop', 'acceptedAnswer' );
			$processor->set_attribute( 'itemtype', 'https://schema.org/Answer' );

			// Add attribute to first paragraph.
			if ( $processor->next_tag( 'p' ) ) {
				$processor->set_attribute( 'itemprop', 'text' );
			}
		}
	}

	return $processor->get_updated_html();
}

Props to @bph and @juanmaguitar for feedback and review on this snippet.

Leave a Reply

Your email address will not be published. Required fields are marked *