问题
I am trying to integrate yoast_breadcrumb API with JSON-LD.
According to the SEO Yoast plugin documentation, I have this breadcrumb code as below:
<?php
yoast_breadcrumb();
?>
However, I am trying to integrate JSON-LD schema with the Yoast Breadcrumb API with follow JSON-LD code example below, and I couldn't find anywhere in the documentation to achieve this, the API displays the HTML format of the breadcrumbList, which is not what I want, I want to have array format so that I would be able to construct the JSON-LD using foreach loop.
{
"@context": "http://schema.org",
"@type": "BreadcrumbList",
"itemListElement":
[
{
"@type": "ListItem",
"position": 1,
"item":
{
"@id": "https://example.com/news/",
"name": "News"
}
},
{
"@type": "ListItem",
"position": 2,
"item":
{
"@id": "https://example.com/news/finance/",
"name": "Finance"
}
}
]
}
回答1:
You can filter the output and collect your JSON. However, in provided example below, the "collect" is maybe to late if you wanna output within the head section of the document. You can then call the breadcrumb function earlier, without echo it and collect the data, remove the filter and render the JSON.
/* echo breadcrumbs in template */
yoast_breadcrumb('<p id="breadcrumbs">','</p>');
/* collect breadcrumb whenever */
$breadcrumbs = yoast_breadcrumb('','',false);
And here is the filter function:
add_filter('wpseo_breadcrumb_links', 'entex_add_crumb_schema', 10, 1);
function entex_add_crumb_schema($crumbs) {
if( ! is_array( $crumbs ) || $crumbs === array()){
return $crumbs;
}
$last = count($crumbs);
$listItems = [];
$j = 1;
foreach ( $crumbs as $i => $crumb ) {
$item = [];
$nr = ($i + 1);
if(isset($crumb['id'])){
$item = [
'@id' => get_permalink($crumb['id']),
'name' => strip_tags( get_the_title( $id ) )
];
}
if(isset($crumb['term'])){
$term = $crumb['term'];
$item = [
'@id' => get_term_link( $term ),
'name' => $term->name
];
}
if(isset($crumb['ptarchive'])){
$postType = get_post_type_object($crumb['ptarchive']);
$item = [
'@id' => get_post_type_archive_link($crumb['ptarchive']),
'name' => $postType->label
];
}
/* READ NOTE BELOW: */
if($nr == $last){
if(is_author() && !isset($crumb['url'])) $crumb['url'] = esc_url(get_author_posts_url(get_queried_object_id()));
}
/* The 'text' indicates the current (last) or start-path crumb (home)*/
if(isset($crumb['url'])) {
if($crumb['text'] !== '') {
$title = $crumb['text'];
} else {
$title = get_bloginfo('name');
}
$item = [
'@id' => $crumb['url'],
'name' => $title
];
}
$listItem = [
'@type' => 'ListItem',
'position' => $j,
'item' => $item
];
$listItems[] = $listItem;
$j++;
}
$schema = [
'@context' => 'http://schema.org',
'@type' => 'BreadcrumbList',
'itemListElement' => $listItems
];
$html = '<script type="application/ld+json">' . stripslashes(json_encode($schema, JSON_PRETTY_PRINT)) . '</script> ';
echo $html;
remove_filter('wpseo_breadcrumb_links', 'entex_add_crumb_schema', 10, 1);
return $crumbs;
}
(*) NOTE Yoast doesnt populate the urls to current landing-pages/ archive landing pages. You have to add those with the example for the author archive in the function. This depends if you want the current trail or not in the schema, so I leave this to be modified at each user case.
(*) TIPS This is RAW examples. Do some sanitazion on your populated vars, to avoid javascript scope issues. Also the last stripslashes is only needed if you use PRETTY arguments.
Happy JSON
来源:https://stackoverflow.com/questions/41053348/wp-seo-yoast-plugin-breadcrumb-and-json-ld-breadcrumblist-integration