🐱

【Wordpress開発】リッチリザルトをテーマレベルで対応する

2021/07/05に公開

wordpressはさまざまなプラグインがあり便利ですが、機能を1つ1つ追加しているとプラグインの山となり、パフォーマンスに影響します。
ライトな機能についてはプラグインをできる限り使用せず、自分で実装していく方がいいと思います。

Wordpressでリッチリザルトに対応する

カスタムフィールドを使用して、スクリプトを貼り付けるという方法もあるようですが、業務レベルで考えた時に、より柔軟に対応できるた方が良いです。
今回、FAQのリッチリザルトを実装していきますが、顧客が管理画面上で顧客が新しいFAQ項目を追加したときに、スクリプトを貼り付けてもらって…というのは現実的ではありません。
レシピブログなどの場合も同様でしょう。

顧客が自由に追加/削除したFAQ項目をリッチリザルト化するために、カスタムフィールドを使い、テーマレベルでリッチリザルトに対応していきます。

そもそもリッチリザルトとは

リッチリザルトとは、Googleの検索で表示される時に、視覚的にも機能的にも見やすく表示される機能であり、目的ごとに様々な形式が用意されています。
例えば、

  • レシピ
  • FAQ
  • 商品

などです。

詳しくは。こちらから

いざ実装

カスタムフィールドで必要項目を作成

今回はFAQなので、

  • question
  • answer

という2つのカスタムフィールドを作成します。
カスタムフィールドはアドバンスドカスタムフィールドというプラグインを使います。

ユーザーが管理しやすいよう、FAQ専用のカスタム投稿を作り、先程のカスタムフィールドの表示設定を済ませておきます。

メインのファイルを作成…の前に、確認。

FAQリッチリザルトのフォーマットを確認しておきます。

 <script type="application/ld+json">
    {
      "@context": "https://schema.org",
      "@type": "FAQPage",
      "mainEntity": [{
        "@type": "Question",
        "name": "質問文1",
        "acceptedAnswer": {
          "@type": "Answer",
          "text": "質問文1に対する答え"
        }
      }, 
           {
        "@type": "Question",
        "name": "質問文2",
        "acceptedAnswer": {
          "@type": "Answer",
          "text": "質問文2に対する答え"
        }
      },
          ]
    }
    </script>

見てわかる通り、mainEntity内の要素がFAQコンテンツの内容となります。
ですので、

{
"@type": "Question",
"name": "質問文",
"acceptedAnswer": {
  "@type": "Answer",
  "text": "質問文に対する答え"
}

ここの部分をループで回して、動的にjsonを生成します。
PHPではそのままjsonを扱えないので、まずは連想配列として生成したのち、json_encode()関数でエンコードします。

メインとなるファイル

themes/myTheme/template-parts/faq-contens.phpを作成します。

<?php
    function addArray($name, $text){
        return array(
            "@type" => "Question",
            "name" => $name,
            "acceptedAnswer" => array("@type" => "Answer","text" => $text)
            );
    }
    $contents = array("@context" => "https://schema.org","@type"=> "FAQPage");


    $args = array(
        'post_type' => 'faq',
        'order' =>  'ASC'
        );
    $the_query = new WP_Query($args); if($the_query->have_posts()):
        $count = $the_query->post_count;
?>

<script type="application/ld+json">
        <?php
        $main = array();
        while ($the_query->have_posts()): $the_query->the_post();
            $q = get_field("question");
            $as = get_field("answer");
            $main = addArray($q, $as);
            $a[] = $main;
        ?>


    <?php endwhile; ?>
    <?php $result = $contents + array("mainEntity" => $a);?>
    <?php echo json_encode($result, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);?>
    <?php wp_reset_postdata(); ?>
    <?php else: ?>
    <!-- 投稿が無い場合の処理 -->
<?php endif; ?>
</script>

上から順に説明します。

  • function addArray($name, $text)
    質問文と回答を返す関数です。

  • $contents = array("@context" => "https://schema.org","@type"=> "FAQPage");
    ループとは関係のない部分をあらかじめ連想配列として用意しておきます。

  • <?php
          $main = array();
          while ($the_query->have_posts()): $the_query->the_post();
              $q = get_field("question");
              $as = get_field("answer");
              $main = addArray($q, $as);
              $a[] = $main;
     ?>
     
    

WPQueryでカスタム投稿を取得し、whileループの中で値を取得。get_fiel()はアドバンスドカスタムフィールドの値を取得する関数です。
the_field()で直接吐き出すこともできますが、うまくいかなかったので一旦代入しています。
ソースコードを確認しておりませんが、おそらくthe_field()が呼ばれた時点で値が出力されてしまうためです。

header.phpから呼び出す

// 追記
<?php if(is_page('faq')): ?>
    <?php get_template_part( 'template-parts/faq-contents'); ?>
<?php endif; ?>
//ここまで
<?php wp_head(); ?>

if文で表示ページの判定を行い、先程のメインファイルを表示します。

表示結果

<script type="application/ld+json">
{
    "@context": "https://schema.org",
    "@type": "FAQPage",
    "mainEntity": [
        {
            "@type": "Question",
            "name": hoge,
            "acceptedAnswer": {
                "@type": "Answer",
                "text": "huga"
            }
        },
        {
            "@type": "Question",
            "name": piyo,
            "acceptedAnswer": {
                "@type": "Answer",
                "text": "yaa"
            }
        }
    ]
}
</script>

テスト

Googleのリッチリザルトテストページでテストします。
https://search.google.com/test/rich-results?hl=ja

まとめ

カスタム投稿を使うことで、様々なシーンに対応できるかと思います。
例えばレシピや商品を扱うページでも今回の方法を取ることで柔軟なテーマ開発ができます。
もっと良い方法もあるかもしれませんが、参考にしていただければ幸いです。

以上。

Discussion