COLUMN

コラム

CATEGORY
  • 「JSON-LD」でパンくずリストの構造化データを実装【カスタマイズ編】

2021.05.21Web制作

「JSON-LD」でパンくずリストの構造化データを実装【カスタマイズ編】

サツキ
サツキ
トリック or トリート! とりあえずお菓子ください。

皆さん、こんにちは。サツキです。

前回の記事で、「JSON-LD」形式のパンくずリストの構造化データをWordPressに実装する方法の記事を書かせていただきました。
今回は、その際に紹介させていただいた「JSON-LD」形式の構造化データの自動生成関数の簡単なカスタマイズ(投稿に対応)方法を紹介させていただきます。

以前の記事をまだ見ていない方は以下のURLより御覧ください。
「JSON-LD」でパンくずリストの構造化データを実装【WP設置編】

自動生成関数を投稿対応にカスタマイズ

以前の記事で紹介させていただいた構造化データの自動生成関数はデフォルトの「投稿」には対応していないものでした。
より正確に言うのであればデフォルトの「投稿」の情報は構造化データの中に含めない仕様のものでした。
ですので、「投稿」の詳細ページ等で構造化データが表示されないのではなく以下の例のように「投稿」情報(一覧ページの情報)が省かれたものになっていました。

例)SAMPLE詳細ページ
<script type="application/ld+json">
  {
    "@context":"http://schema.org",
    "@type":"BreadcrumbList",
    "name":"パンくずリスト",
    "itemListElement":[
      {
        "@type":"ListItem",
        "position":1,
        "item":{"name":"HOME","@id":"https://sample.com/"}
      },
      {
        "@type":"ListItem",
        "position":2,
        "item":{"name":"デフォルト投稿詳細ページ","@id":"https://sample.com/sample/"}
      }
    ]
  }
</script>

なぜそのようにしているかと言うと以下のような理由があります。
・私自身がWordPressを使いサイト制作を行う際にデフォルトの「投稿」「カテゴリ」「タグ」を使用しないようにしていること。
・WordPressはデフォルトではTOPページにあたるページがブログ一覧ページになっているため、TOPページとブログ一覧とを分ける場合には管理画面でいくつかの設定をする必要があること。
・デフォルトの「投稿」の名称を変更するためには追加で「functions.php」内に記述が必要なこと。(※デフォルトでは「投稿」という名前なのでパンくずリストに表示させる際に名前の変更を行いたい場合)

ですが、デフォルトの「投稿」をそのまま使用してサイトを構築する方も普通にいるかと思いますのでその方法を紹介しようと思います。

1. WordPress管理画面でTOPページとブログ一覧ページとを分ける

まず管理画面「固定ページ」でフロントページ(トップページ)と投稿ページ(ブログ一覧)用の固定ページを作成します。
それから、管理画面「設定」の「表示設定」で【ホームページの表示】項目の設定を「最新の投稿」から「固定ページ」に変更の上で【ホームページ: 】と【投稿ページ:】のセレクトボックスで先ほど作成したページを設定する。

json_cus_01

また必ず必要なわけではありませんが、管理画面「設定」の「パーマリンク設定」で【共通設定】項目をカスタム構造を選択の上で「/{作成したブログ一覧ページのslug}/%post_id%/」と設定いただくと詳細ページのURL構造がブログ一覧ページ以下に変更できますので設定しておくといいかと思います。

json_cus_02

2. デフォルト投稿の名称を変更

この作業も必ず必要なわけではありませんが、ブログもしくはお知らせ等としてデフォルトの「投稿」を使用する際に構造化データ上の一覧ページの名称が現状では「ブログ(もしくはお知らせ)」でなく「投稿」と出てしまいます。
ここの名称も変更したいというケースもあるかと思いますのでその方法をご紹介します。
テーマ内の「functions.php」内に以下のコードを追記してください。
もしブログという名前以外に変更する場合は「change_post_menu_label()」「change_post_menu()」関数内の「$name」の値を変更してください。

例)ブログという名前にする場合
function change_post_menu_label() {
 global $menu, $submenu;
 $name = 'ブログ';
 $menu[5][0] = $name;
 $submenu['edit.php'][5][0] = $name. '一覧';
 $submenu['edit.php'][10][0] = '新規' .$name;
}
function change_post_menu() {
 global $wp_post_types;
 $name = 'ブログ';
 $wp_post_types['post']->label = $name;
 $labels = &$wp_post_types['post']->labels;
 $labels->name = $name;
 $labels->singular_name = $name;
 $labels->add_new = $name. '新規追加';
 $labels->add_new_item = $name. 'の新規追加';
 $labels->edit_item = $name. 'の編集';
 $labels->new_item = '新規' .$name;
 $labels->view_item = $name. 'を表示';
 $labels->search_items = $name. 'を検索';
 $labels->not_found = $name. 'が見つかりませんでした';
 $labels->not_found_in_trash = 'ゴミ箱に' .$name. 'は見つかりませんでした';
}
add_action( 'admin_menu', 'change_post_menu_label' );
add_action( 'init', 'change_post_menu' );

3. 自動生成関数をカスタマイズ

変更点としては、以下になります。
・3行目の非表示ページの対象から「is_home()」を削除
・「is_post_type_archive()」の分岐に「is_home()」の分岐も追加し、両方に対応できるように修正
・「is_tax() || is_category()」と「is_single()」の分岐でデフォルト「投稿」の時でも情報を表示するように修正

function json_breadcrumb() {

  if( is_admin() || is_front_page() ){ return; }

  $position  = 1;
  $query_obj = get_queried_object();
  $permalink = ( empty($_SERVER["HTTPS"] ) ? "http://" : "https://") . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];

  $json_breadcrumb = array(
    "@context"        => "http://schema.org",
    "@type"           => "BreadcrumbList",
    "name"            => "パンくずリスト",
    "itemListElement" => array(
      array(
        "@type"    => "ListItem",
        "position" => $position++,
        "item"     => array(
          "name" => "HOME",
          "@id"  => esc_url( home_url('/') ),
        )
      ),
    ),
  );

  if( is_page() ) {

    $ancestors   = get_ancestors( $query_obj->ID, 'page' );
    $ancestors_r = array_reverse($ancestors);
    if ( count( $ancestors_r ) != 0 ) {
      foreach ($ancestors_r as $key => $ancestor_id) {
        $ancestor_obj = get_post($ancestor_id);
        $json_breadcrumb['itemListElement'][] = array(
          "@type"    => "ListItem",
          "position" => $position++,
          "item"     => array(
            "name" => esc_html($ancestor_obj->post_title),
            "@id"  => esc_url( get_the_permalink($ancestor_obj->ID) ),
          )
        );
      }
    }
    $json_breadcrumb['itemListElement'][] = array(
      "@type"    => "ListItem",
      "position" => $position++,
      "item"     => array(
        "name" => esc_html($query_obj->post_title),
        "@id"  => $permalink,
      )
    );

  } elseif( is_post_type_archive() || is_home() ) {

    $pt_obj = ( is_home() ) ? get_post_type_object('post'): $query_obj;
    $json_breadcrumb['itemListElement'][] = array(
      "@type"    => "ListItem",
      "position" => $position++,
      "item"     => array(
        "name" => $pt_obj->label,
        "@id"  => esc_url( get_post_type_archive_link( $pt_obj->name ) ),
      )
    );

  } elseif( is_tax() || is_category() ) {

    $post_type = get_taxonomy( $query_obj->taxonomy )->object_type[0];
    $pt_obj    = get_post_type_object( $post_type );
    $json_breadcrumb['itemListElement'][] = array(
      "@type"    => "ListItem",
      "position" => $position++,
      "item"     => array(
        "name" => $pt_obj->label,
        "@id"  => esc_url( get_post_type_archive_link($pt_obj->name) ),
      )
    );

    $ancestors   = get_ancestors( $query_obj->term_id, $query_obj->taxonomy );
    $ancestors_r = array_reverse($ancestors);
    foreach ($ancestors_r as $key => $ancestor_id) {
      $json_breadcrumb['itemListElement'][] = array(
        "@type"    => "ListItem",
        "position" => $position++,
        "item"     => array(
          "name" => esc_html( get_cat_name($ancestor_id) ),
          "@id"  => esc_url( get_term_link($ancestor_id, $query_obj->taxonomy) ),
        )
      );
    }

    $json_breadcrumb['itemListElement'][] = array(
      "@type"    => "ListItem",
      "position" => $position++,
      "item"     => array(
        "name" => esc_html( $query_obj->name ),
        "@id"  => esc_url( get_term_link($query_obj) ),
      )
    );

  } elseif( is_single() ) {

    $pt_obj = get_post_type_object( $query_obj->post_type );
    $json_breadcrumb['itemListElement'][] = array(
      "@type"    => "ListItem",
      "position" => $position++,
      "item"     => array(
        "name" => $pt_obj->label,
        "@id"  => esc_url( get_post_type_archive_link($pt_obj->name) ),
      )
    );

    $json_breadcrumb['itemListElement'][] = array(
      "@type"    => "ListItem",
      "position" => $position++,
      "item"     => array(
        "name" => esc_html( $query_obj->post_title ),
        "@id"  => $permalink,
      )
    );

  } elseif( is_404() ) {

    $json_breadcrumb['itemListElement'][] = array(
      "@type"    => "ListItem",
      "position" => $position++,
      "item"     => array(
        "name" => "404 Not found",
        "@id"  => $permalink,
      )
    );

  } elseif( is_search() ) {

    $json_breadcrumb['itemListElement'][] = array(
      "@type"    => "ListItem",
      "position" => $position++,
      "item"     => array(
        "name" => "「" . get_search_query(). "」の検索結果",
        "@id"  => $permalink,
      )
    );

  }

  echo '<script type="application/ld+json">'.json_encode($json_breadcrumb).'</script>';
}

add_action( 'wp_head', 'json_breadcrumb' );

まとめ

以上が、前回ご紹介したパンくずリストの構造化データの自動生成関数をデフォルト「投稿」にも対応させる方法となります。
前回同様にそこまで難しいということもないかと思いますのでデフォルト「投稿」を使用してサイトを構築されている方は是非一度お試しください。
次回以降も引き続き「JSON-LD」に関わる話をさせていただこうと思います。

それでは今回も最後までお付き合いありがとうございました。

採用サイトデザインに特化したまとめサイト | DEZDEZ デザデザ