パンくずリストを残したまま。「警告:data-vocabulary.org schema deprecated」の解決策

Sponsored Link

こんにちは。ひかるです。

ある日突然「パンくずリスト」に関するエラーが通知されました。

今までのエラー通知の中で「パンくずリスト」に関するものはなかったのでびっくりしたのですが、ちょっとググってみるとどうやらGoogle側の仕様変更によるとのこと(割愛)。

詳細については、こちらが参考になります。

>>パンくずリストの構造化 DATA-VOCABULARY.ORG SCHEMA DEPRECATED エラーの改善方法

構造化データのマークアップ「data-vocabulary.org」から「Schema.org」へ移行する

調べてみると、このブログも「data-vocabulary.org」にてマークアップされていることが判明。これをSchema.orgへ移行すれば問題解決になると。

このブログはWordPressにて、テーマは「STORK(ストーク)」を使用しています。

STORKは「function.php」ファイルの「// breadcrumb」にパンくずリストに関するコードが記述されています。ここを修正します。

既存の「パンくずリスト」から構造化マークアップ要素を削除する

STORKでは「//// breadcrumb」にて、パンくずリストの出力と同時に「data-vocabulary.org」でのマークアップをするように記述されています。

  • パンくずリスト
  • 「data-vocabulary.org」マークアップ

これを「Schema.org」でマークアップするよう書き換えればいいのですが。。

  • パンくずリスト
  • 「Schema.org」マークアップ

そうそう簡単な話ではなかったのでした。いくつか参考にしながらSTORKに合わせてリライトしてみたのですがどうしてもうまくいかず。。

>>data-vocabulary.org schema deprecated の警告が出た!パンくずリストの構造化データを修正しましょう

>>「パンくずリスト」の問題が新たに検出されました。data-vocabulary.org schema deprecatedとは?

そこで「// breadcrumb」から「data-vocabulary.org」マークアップの関する部分を削除し、「// breadcrumb」の後に新たなマークアップを追加する記述を追加する、という変更にしました。

  • // breadcrumb
  • パンくずリスト

次に、

  • // 追加
  • 別方法でマークアップ

文章だと意味不明かもしれませんが、コードで説明するとSTORKの「function.php」のパンくずリストに関する部分は次のように記述されています。

// breadcrumb
if (!function_exists(‘breadcrumb’)) {
function breadcrumb($divOption = array(“id” => “breadcrumb”, “class” => “breadcrumb inner wrap cf”)){
global $wp_query;
global $post;
$str =”;
if(get_option(‘side_options_pannavi’, ‘pannavi_on’) !== ‘pannavi_off’){
if(!is_home()&&!is_front_page()&&!is_admin() ){
$tagAttribute = ”;
foreach($divOption as $attrName => $attrValue){
$tagAttribute .= sprintf(‘ %s=”%s”‘, $attrName, $attrValue);
}
$str.= ‘<div’. $tagAttribute .’>’;
$str.= ‘<ul>’;
$str.= ‘<li itemscope itemtype=”//data-vocabulary.org/Breadcrumb” class=”bc_homelink”><a href=”‘. esc_url(home_url( ‘/’ )) .'” itemprop=”url”><span itemprop=”title”> HOME</span></a></li>’;

if(is_category()) {
$cat = get_queried_object();
if($cat -> parent != 0){
$ancestors = array_reverse(get_ancestors( $cat -> cat_ID, ‘category’ ));
foreach($ancestors as $ancestor){
$str.='<li itemscope itemtype=”//data-vocabulary.org/Breadcrumb”><a href=”‘. get_category_link($ancestor) .'” itemprop=”url”><span itemprop=”title”>’. get_cat_name($ancestor) .'</span></a></li>’;
}
}
$str.='<li itemscope itemtype=”//data-vocabulary.org/Breadcrumb”><span itemprop=”title”>’. $cat -> name . ‘</span></li>’;
} elseif ( is_post_type_archive() ) {
$cpt = get_query_var( ‘post_type’ );
$str.= ‘<li>’ . get_post_type_object( $cpt )->label . ‘</li>’;
} elseif ( is_tax() ) {
//taxonomy
$query_obj = get_queried_object();
$post_types = get_taxonomy( $query_obj->taxonomy )->object_type;
$cpt = $post_types[0];
$str.= ‘<li><a href=”‘. get_post_type_archive_link( $cpt ) . ‘” itemprop=”url”><span itemprop=”title”>’. get_post_type_object( $cpt )->label .'</span></a></li>’;
$taxonomy = get_query_var( ‘taxonomy’ );
$term = get_term_by( ‘slug’, get_query_var( ‘term’ ), $taxonomy );
if ( is_taxonomy_hierarchical( $taxonomy ) && $term->parent != 0 ) {
$ancestors = array_reverse( get_ancestors( $term->term_id, $taxonomy ) );
foreach ( $ancestors as $ancestor_id ) {
$ancestor = get_term( $ancestor_id, $taxonomy );
$str.='<li itemscope itemtype=”//data-vocabulary.org/Breadcrumb”><a href=”‘. get_term_link( $ancestor, $term->slug ) .'” itemprop=”url”><span itemprop=”title”>’. $ancestor->name .'</span></a></li>’;
}
}
$str.='<li>’. $term->name .'</li>’;
} elseif(is_single()){
$post_type = get_post_type( $post->ID );
if ( $post_type == ‘post’ ) {
// normal post
$categories = get_the_category($post->ID);
$cat = $categories[0];
if($cat -> parent != 0){
$ancestors = array_reverse(get_ancestors( $cat -> cat_ID, ‘category’ ));
foreach($ancestors as $ancestor){
$str.='<li itemscope itemtype=”//data-vocabulary.org/Breadcrumb”><a href=”‘. get_category_link($ancestor).'” itemprop=”url”><span itemprop=”title”>’. get_cat_name($ancestor). ‘</span></a></li>’;
}
}
$str.='<li itemscope itemtype=”//data-vocabulary.org/Breadcrumb”><a href=”‘. get_category_link($cat -> term_id). ‘” itemprop=”url”><span itemprop=”title”>’. $cat-> cat_name . ‘</span></a></li>’;
$str.= ‘<li>’. $post -> post_title .'</li>’;
} else {
// custom post type
$post_type_object = get_post_type_object( $post->post_type );
if($post_type_object->has_archive !== false){
$str.='<li itemscope itemtype=”//data-vocabulary.org/Breadcrumb”><a href=”‘. get_post_type_archive_link(get_post_type()) .'” itemprop=”url”><span itemprop=”title”>’. $post_type_object->labels->name .'</a></span></li>’;
}
$str.= ‘<li>’. $post -> post_title .'</li>’;
}
} elseif(is_page()){
if($post -> post_parent != 0 ){
$ancestors = array_reverse(get_post_ancestors( $post->ID ));
foreach($ancestors as $ancestor){
$str.='<li itemscope itemtype=”//data-vocabulary.org/Breadcrumb”><a href=”‘. get_permalink($ancestor).'” itemprop=”url”><span itemprop=”title”>’. get_the_title($ancestor) .'</span></a></li>’;
}
}
$str.= ‘<li>’. $post -> post_title .'</li>’;
} elseif(is_date()){
if( is_year() ){
$str.= ‘<li>’ . get_the_time(‘Y’) . ‘年</li>’;
} else if( is_month() ){
$str.= ‘<li><a href=”‘ . get_year_link(get_the_time(‘Y’)) .'”>’ . get_the_time(‘Y’) . ‘年</a></li>’;
$str.= ‘<li>’ . get_the_time(‘n’) . ‘月</li>’;
} else if( is_day() ){
$str.= ‘<li><a href=”‘ . get_year_link(get_the_time(‘Y’)) .'”>’ . get_the_time(‘Y’) . ‘年</a></li>’;
$str.= ‘<li><a href=”‘ . get_month_link(get_the_time(‘Y’),get_the_time(‘m’)) . ‘”>’ . get_the_time(‘n’) . ‘月</a></li>’;
$str.= ‘<li>’ . get_the_time(‘j’) . ‘日</li>’;
}
if(is_year() && is_month() && is_day() ){
$str.= ‘<li>’ . wp_title(”, false) . ‘</li>’;
}
} elseif(is_search()) {
$str.='<li itemscope itemtype=”//data-vocabulary.org/Breadcrumb”><span itemprop=”title”>「’. get_search_query() .’」で検索した結果</span></li>’;
} elseif(is_author()){
$str .='<li itemscope itemtype=”//data-vocabulary.org/Breadcrumb”><span itemprop=”title”>投稿者 : ‘. get_the_author_meta(‘display_name’, get_query_var(‘author’)).'</span></li>’;
} elseif(is_tag()){
$str.='<li itemscope itemtype=”//data-vocabulary.org/Breadcrumb”><span itemprop=”title”>タグ : ‘. single_tag_title( ” , false ). ‘</span></li>’;
} elseif(is_attachment()){
$str.= ‘<li><span itemprop=”title”>’. $post -> post_title .'</span></li>’;
} elseif(is_404()){
$str.='<li>ページがみつかりません。</li>’;
} else{
$str.='<li></li>’;
}
$str.='</ul>’;
$str.='</div>’;
}
}
echo $str;
}
}

パンくずリストをhtmlに出力すると同時に、data-vocabulary.orgでの構造化マークアップをしています。

ここからマークアップの記述のみ削除します。

if (!function_exists(‘breadcrumb’)) {
function breadcrumb($divOption = array(“id” => “breadcrumb”, “class” => “breadcrumb inner wrap cf”)){
global $wp_query;
global $post;
$str =”;
if(get_option(‘side_options_pannavi’, ‘pannavi_on’) !== ‘pannavi_off’){
if(!is_home()&&!is_front_page()&&!is_admin() ){
$tagAttribute = ”;
foreach($divOption as $attrName => $attrValue){
$tagAttribute .= sprintf(‘ %s=”%s”‘, $attrName, $attrValue);
}
$str.= ‘<div’. $tagAttribute .’>’;
$str.= ‘<ul>’;
$str.= ‘<li class=”bc_homelink”><a href=”‘. esc_url(home_url( ‘/’ )) .'”> HOME</a></li>’;

if(is_category()) {
$cat = get_queried_object();
if($cat -> parent != 0){
$ancestors = array_reverse(get_ancestors( $cat -> cat_ID, ‘category’ ));
foreach($ancestors as $ancestor){
$str.='<li><a href=”‘. get_category_link($ancestor) .'”>’. get_cat_name($ancestor) .'</a></li>’;
}
}
$str.='<li>’. $cat -> name . ‘</li>’;
} elseif ( is_post_type_archive() ) {
$cpt = get_query_var( ‘post_type’ );
$str.= ‘<li>’ . get_post_type_object( $cpt )->label . ‘</li>’;
} elseif ( is_tax() ) {
//taxonomy
$query_obj = get_queried_object();
$post_types = get_taxonomy( $query_obj->taxonomy )->object_type;
$cpt = $post_types[0];
$str.= ‘<li><a href=”‘. get_post_type_archive_link( $cpt ) . ‘”>’. get_post_type_object( $cpt )->label .'</a></li>’;
$taxonomy = get_query_var( ‘taxonomy’ );
$term = get_term_by( ‘slug’, get_query_var( ‘term’ ), $taxonomy );
if ( is_taxonomy_hierarchical( $taxonomy ) && $term->parent != 0 ) {
$ancestors = array_reverse( get_ancestors( $term->term_id, $taxonomy ) );
foreach ( $ancestors as $ancestor_id ) {
$ancestor = get_term( $ancestor_id, $taxonomy );
$str.='<li><a href=”‘. get_term_link( $ancestor, $term->slug ) .'”>’. $ancestor->name .'</a></li>’;
}
}
$str.='<li>’. $term->name .'</li>’;
} elseif(is_single()){
$post_type = get_post_type( $post->ID );
if ( $post_type == ‘post’ ) {
// normal post
$categories = get_the_category($post->ID);
$cat = $categories[0];
if($cat -> parent != 0){
$ancestors = array_reverse(get_ancestors( $cat -> cat_ID, ‘category’ ));
foreach($ancestors as $ancestor){
$str.='<li><a href=”‘. get_category_link($ancestor).'”>’. get_cat_name($ancestor). ‘</a></li>’;
}
}
$str.='<li><a href=”‘. get_category_link($cat -> term_id). ‘”>’. $cat-> cat_name . ‘</a></li>’;
$str.= ‘<li>’. $post -> post_title .'</li>’;
} else {
// custom post type
$post_type_object = get_post_type_object( $post->post_type );
if($post_type_object->has_archive !== false){
$str.='<li><a href=”‘. get_post_type_archive_link(get_post_type()) .'”>’. $post_type_object->labels->name .'</a></li>’;
}
$str.= ‘<li>’. $post -> post_title .'</li>’;
}
} elseif(is_page()){
if($post -> post_parent != 0 ){
$ancestors = array_reverse(get_post_ancestors( $post->ID ));
foreach($ancestors as $ancestor){
$str.='<li><a href=”‘. get_permalink($ancestor).'”>’. get_the_title($ancestor) .'</a></li>’;
}
}
$str.= ‘<li>’. $post -> post_title .'</li>’;
} elseif(is_date()){
if( is_year() ){
$str.= ‘<li>’ . get_the_time(‘Y’) . ‘年</li>’;
} else if( is_month() ){
$str.= ‘<li><a href=”‘ . get_year_link(get_the_time(‘Y’)) .'”>’ . get_the_time(‘Y’) . ‘年</a></li>’;
$str.= ‘<li>’ . get_the_time(‘n’) . ‘月</li>’;
} else if( is_day() ){
$str.= ‘<li><a href=”‘ . get_year_link(get_the_time(‘Y’)) .'”>’ . get_the_time(‘Y’) . ‘年</a></li>’;
$str.= ‘<li><a href=”‘ . get_month_link(get_the_time(‘Y’),get_the_time(‘m’)) . ‘”>’ . get_the_time(‘n’) . ‘月</a></li>’;
$str.= ‘<li>’ . get_the_time(‘j’) . ‘日</li>’;
}
if(is_year() && is_month() && is_day() ){
$str.= ‘<li>’ . wp_title(”, false) . ‘</li>’;
}
} elseif(is_search()) {
$str.='<li>「’. get_search_query() .’」で検索した結果</li>’;
} elseif(is_author()){
$str .='<li>投稿者 : ‘. get_the_author_meta(‘display_name’, get_query_var(‘author’)).'</li>’;
} elseif(is_tag()){
$str.='<li>タグ : ‘. single_tag_title( ” , false ). ‘</li>’;
} elseif(is_attachment()){
$str.= ‘<li>’. $post -> post_title .'</li>’;
} elseif(is_404()){
$str.='<li>ページがみつかりません。</li>’;
} else{
$str.='<li></li>’;
}
$str.='</ul>’;
$str.='</div>’;
}
}
echo $str;
}
}

具体的には3つの部分についての削除です。

  • li「itemscope itemtype=”//data-vocabulary.org/Breadcrumb”」
  • a「itemprop=”url”」
  • <span itemprop=”title”>

JSON-LDのマークアップを追加する

先の変更ではパンくずリストは残りましたが、構造化マークアップがされなくなりました。次にJSON-LDにてマークアップするコードを記述をします。JSON-LDはSchema.orgよりでマークアップするよりも便利なのだそう(そうなの?)。

こちらのコードを参考にしました。GoogleはJSON-LDでのマークアップを推奨しています。

>>Google|構造化データの仕組みについて

>>プラグインを使わずに記事詳細ページのパンくずをJSON-LDで構造化

// 追加
function bcStructure(){
global $post;
$my_taxonomy = get_query_var(‘taxonomy’);
$cpt = get_query_var(‘post_type’);
$str =”;
$str.= ‘<script type=”application/ld+json”>{“@context”: “http://schema.org”,”@type”: “BreadcrumbList”,”itemListElement”:[‘;

if (get_post_type() === ‘post’ && is_single()) {
$categories = get_the_category($post->ID);
$cat = get_youngest_cat($categories);
$count = 1;
if($cat -> parent != 0){
$ancestors = array_reverse(get_ancestors( $cat -> cat_ID, ‘category’ ));

foreach($ancestors as $ancestor){
$str.= ‘{“@type”: “ListItem”,”position”: ‘.$count.’,”item”:{‘;
$str.= ‘”@id”:”‘.get_category_link($ancestor).'”,”name”:”‘. get_cat_name($ancestor).'”}},’;
$count++;
}
}
$str.= ‘{“@type”: “ListItem”,”position”: ‘.$count.’,”item”:{‘;
$str.= ‘”@id”:”‘. get_category_link($cat -> term_id). ‘”,”name”:”‘. $cat-> cat_name . ‘”}},’;
$count++;
$str.= ‘{“@type”: “ListItem”,”position”: ‘.$count.’,”item”:{‘;
$str.= ‘”@id”:”‘ . get_permalink($post -> post_id) . ‘”,”name”:”‘ . $post -> post_title .'”}}’ ;

}elseif($cpt && is_singular($cpt)){
$taxes = get_object_taxonomies( $cpt );
$mytax = $taxes[0];

$count = 1;
$str.= ‘{“@type”: “ListItem”,”position”: ‘.$count.’,”item”:{‘;
$str.= ‘”@id”:”‘.get_post_type_archive_link($cpt).'”,”name”:”‘. get_post_type_object($cpt)->label.'”}},’;
$count++;

$taxes = get_the_terms($post->ID, $mytax);
$tax = get_youngest_tax($taxes, $mytax );
if($tax -> parent != 0){
$ancestors = array_reverse(get_ancestors( $tax -> term_id, $mytax ));
foreach($ancestors as $ancestor){
$str.= ‘{“@type”: “ListItem”,”position”: ‘.$count.’,”item”:{‘;
$str.= ‘”@id”:”‘. get_term_link($ancestor, $mytax).'”,”name”:”‘. get_term($ancestor, $mytax)->name . ‘”}},’;
$count++;
}
}
$str.= ‘{“@type”: “ListItem”,”position”: ‘.$count.’,”item”:{‘;
$str.= ‘”@id”:”‘. get_term_link($tax, $mytax).'”,”name”:”‘. $tax -> name .'”}},’;
$count++;
$str.= ‘{“@type”: “ListItem”,”position”: ‘.$count.’,”item”:{‘;
$str.= ‘”@id”:”‘ . get_permalink($post -> post_id) . ‘”,”name”:”‘ . $post -> post_title .'”}}’ ;
}

$str.= ‘]}</script>’;
echo $str;
}
function get_youngest_cat($categories){
global $post;
if(count($categories) == 1 ){
$youngest = $categories[0];
}
else{
$count = 0;
foreach($categories as $category){
$children = get_term_children( $category -> term_id, ‘category’ );
if($children){
if ( $count < count($children) ){
$count = count($children);
$lot_children = $children;
foreach($lot_children as $child){
if( in_category( $child, $post -> ID ) ){
$youngest = get_category($child);
}
}
}
}
else{
$youngest = $category;
}
}
}
return $youngest;
}
function get_youngest_tax($taxes, $mytaxonomy){
global $post;
if(count($taxes) == 1 ){
$youngest = $taxes[key($taxes)];
}
else{
$count = 0;
foreach($taxes as $tax){
$children = get_term_children( $tax -> term_id, $mytaxonomy );
if($children){
if ( $count < count($children) ){
$count = count($children);
$lot_children = $children;
foreach($lot_children as $child){
if( is_object_in_term( $post -> ID, $mytaxonomy ) ){
$youngest = get_term($child, $mytaxonomy);
}
}
}
}
else{
$youngest = $tax;
}
}
}
return $youngest;
}

これはもちろん画面上には表示されないのでご安心を。

ここまでの修正が終わったら「URL検査」にかけてみます。

無事に修正されました。行ったことをまとめます。

  • テーマファイル「function.php」の「// breadcrumb」から「data-vocabulary.org」マークアップ部分を削除
  • 「JSON-LD」にてマークアップするコードを追加

警告「data-vocabulary.org schema deprecated」の解決策(data-vocabulary.orgの廃止)をしたいものの、既存の方法ではうまくできなかったのでエントリーにしました。当方エキスパートではないので、自己責任にてお願いします。

ひかる




コメントを残す

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

ABOUTこの記事をかいた人

2013年大卒。社員3名零細スタートアップベンチャー新卒入社。組織開発コンサルに従事後、17年12月末退職。収入0からリスタート。好きなことやりたいことに素直に!ブログを綴りながら生きていく!人生実験してます。