Skip to content

Instantly share code, notes, and snippets.

@dexit
Forked from Luehrsen/faq_graph_schema.php
Created July 2, 2025 13:57
Show Gist options
  • Save dexit/ae316d7cdd76445ffe6989655238a1a5 to your computer and use it in GitHub Desktop.
Save dexit/ae316d7cdd76445ffe6989655238a1a5 to your computer and use it in GitHub Desktop.
<?php
/**
* Render the schema graph for the acf/gb-faq block.
*
* @param array $graph Schema data for the current page.
* @param WP_Block_Parser_Block $block The block data array.
* @param Meta_Tags_Context $context A value object with context variables.
*
* @return array Our Schema graph.
*/
public function faq_schema( $graph, $block, $context ) {
// Format the block data into the expected format from acf.
$acf_block = acf_prepare_block( $block['attrs'] );
// Setup postdata allowing get_field() to work.
acf_setup_meta( $acf_block['data'], $acf_block['id'], true );
// Find the index of the WebPage Item and add the FAQPage item if necessary.
foreach ( $graph as $index => $graph_piece ) {
if ( isset( $graph_piece['@type'] ) ) {
if ( is_array( $graph_piece['@type'] ) && in_array( 'WebPage', $graph_piece['@type'], true ) ) {
$faqi = $index;
$graph[ $faqi ]['@type'][] = 'FAQPage';
$graph[ $faqi ]['@type'] = array_unique( $graph[ $faqi ]['@type'] );
} elseif ( is_string( $graph_piece['@type'] ) && $graph_piece['@type'] === 'WebPage' ) {
$faqi = $index;
$graph[ $faqi ]['@type'] = array(
'WebPage',
'FAQPage',
);
}
}
}
$graph_questions = array();
// Loop over the questions in the block content.
foreach ( get_field( 'content' ) as $si => $section ) {
if ( $section['acf_fc_layout'] ) {
$section_id = 'section-' . $si . '-' . $acf_block['id'];
foreach ( $section['questions'] as $qi => $q ) {
$question_id = 'question-' . $qi . '-' . $section_id;
// Format the question as per Schema.org spec. But yeah, let's be real
// here, I just looked at how yoast strucures it in their internal FAQ
// block.
$graph_questions[] = array(
'@type' => 'Question',
'@id' => get_permalink() . '#' . $question_id,
'url' => get_permalink() . '#' . $question_id,
'name' => $q['question'],
'answerCount' => 1,
'acceptedAnswer' => array(
'@type' => 'Answer',
'text' => $q['answer'],
'inLanguage' => get_locale(),
),
'inLanguage' => get_locale(),
);
// If we do not yet have a mainEntity, create it.
if ( ! isset( $graph[ $faqi ]['mainEntity'] ) || ! is_array( $graph[ $faqi ]['mainEntity'] ) ) {
$graph[ $faqi ]['mainEntity'] = array();
}
// Hook the question @id into the mainEntity array.
$graph[ $faqi ]['mainEntity'][] = array(
'@id' => get_permalink() . '#' . $question_id,
);
}
}
}
// Reset postdata.
acf_reset_meta( $acf_block['id'] );
// Merge our questions into the main graph array and return.
return array_merge( $graph, $graph_questions );
}
add_action( 'wpseo_schema_block_acf/gb-faq', 'faq_schema', 10, 3 );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment