php - Set Schema Data Dynamically for FAQ Page
I'm attempting to set the schema data of all questions and answers on an FAQ page dynamically using the class name of each question and answer. I cannot use script due to it being overwritten by the SEO by Yoast.
I've created the code below so far, but it's not bringing in the questions and answers into Google's Structured Data Tool and I'm not able to loop each of the questions and answers.
HTML
<div class="x-acc-item">
<span class="question">Can I order for pick up or delivery?
</span>
<div class="answer">
<p>Yes, you can!</p>
</div>
</div>
<div class="x-acc-item">
<span class="question">Do you have a rewards program?</span>
<div class="answer">
<p>We sure do!</p>
</div>
</div>
PHP
add_filter( 'wpseo_schema_webpage', 'change_faq_schema' );
function change_faq_schema( $data ) {
if ( ! is_page( 'frequently-asked-questions' ) ) {
return $data;
}
$schema = array(
'mainEntity' => array()
);
$resultquestion = array();
$resultanswer = array();
$question = "question";
$answer = "answer";
$domdocument = new DOMDocument();
$domdocument->loadHTML($doc);
$a = new DOMXPath($domdocument);
$spans = $a->query("//*[contains(concat(' ', normalize-space(@class), ' '), ' $question ')]");
$spans2 = $a->query("//*[contains(concat(' ', normalize-space(@class), ' '), ' $answer ')]");
for ($i = $spans->length - 1; $i > -1; $i--) {
$resultquestion[] = $spans->item($i)->firstChild->nodeValue;
}
for ($i = $spans2->length - 1; $i > -1; $i--) {
$resultanswer[] = $spans2->item($i)->firstChild->nodeValue;
}
$data['mainEntity'] = array(
'@type' => "Question",
'name' => $resultquestion,
"acceptedAnswer" => array(
"@type" => "Answer",
"text" => $resultanswer
)
);
return $data;
}
Answer
Solution:
You can disable Yoast on specific page, then you can enqueue your own schemas.
As of Yoast SEO 14.0, we've changed the way you can interact with the output of Yoast SEO. However, in some cases, you might want to disable the output coming from Yoast SEO on a specific post.
<?php
add_action( 'template_redirect', 'remove_wpseo' );
/**
* Removes output from Yoast SEO on the frontend for a specific post, page or custom post type.
*/
function remove_wpseo() {
if ( is_single ( 1 ) ) {
$front_end = YoastSEO()->classes->get( Yoast\WP\SEO\Integrations\Front_End_Integration::class );
remove_action( 'wpseo_head', [ $front_end, 'present_head' ], -9999 );
}
}; ?>
More information @ https://developer.yoast.com/customization/yoast-seo/disabling-yoast-seo/
Source