FAQ Section With Schema From an ACF Repeater
Adds an [acf_faq] shortcode that shows a question-and-answer repeater as accessible collapsible items and outputs matching FAQPage structured data.
Opens WPIDE on
Code
add_shortcode( 'acf_faq', function ( $atts ) {
$atts = shortcode_atts( array( 'name' => 'faqs', 'question' => 'question', 'answer' => 'answer' ), $atts, 'acf_faq' );
$post_id = get_the_ID();
if ( ! $post_id || ! function_exists( 'get_field' ) ) {
return '';
}
$rows = get_field( sanitize_key( $atts['name'] ), $post_id );
if ( ! is_array( $rows ) || ! $rows ) {
return '';
}
$html = '<div class="acf-faq">';
$schema = array( '@context' => 'https://schema.org', '@type' => 'FAQPage', 'mainEntity' => array() );
foreach ( $rows as $row ) {
$q = isset( $row[ $atts['question'] ] ) && is_string( $row[ $atts['question'] ] ) ? trim( $row[ $atts['question'] ] ) : '';
$a = isset( $row[ $atts['answer'] ] ) && is_string( $row[ $atts['answer'] ] ) ? trim( $row[ $atts['answer'] ] ) : '';
if ( '' === $q || '' === $a ) {
continue;
}
$html .= '<details class="acf-faq-item"><summary>' . esc_html( $q ) . '</summary><div class="acf-faq-answer">' . wp_kses_post( wpautop( $a ) ) . '</div></details>';
$schema['mainEntity'][] = array(
'@type' => 'Question',
'name' => wp_strip_all_tags( $q ),
'acceptedAnswer' => array( '@type' => 'Answer', 'text' => wp_kses( $a, array( 'a' => array( 'href' => true ), 'strong' => array(), 'em' => array(), 'br' => array(), 'p' => array(), 'ul' => array(), 'ol' => array(), 'li' => array() ) ) ),
);
}
if ( ! $schema['mainEntity'] ) {
return '';
}
return $html . '</div><script type="application/ld+json">' . wp_json_encode( $schema, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_HEX_TAG ) . '</script>';
} );
Notes
Create a repeater named faqs with question and answer sub fields (or change the names). Needs ACF PRO.
How to add this snippet
- Install WPIDE on your WordPress site (it is free) and open Code Snippets.
- Use snippet above adds it from the library in one click. Or copy the code into a new snippet with the same code type.
- It is added inactive: review the code and settings, then switch it on.