検索結果に星評価を表示するWordPressカスタマイズ方法(JSON-LDでレビュー構造化データの出力)

先日、自作のテーマに「検索結果に星評価(レビュースター)を表示する機能」を追加しました。

検索結果に評価星を表示する

これは、Review用のJSON-LDでReview構造化データをheadタグに出力することで実現させることができます。

この機能を、他のテーマでも使用したかったので、機能を切り出してどんなテーマでも使用できるようにコードを書き換えてみました。

なるべく手軽にできるように、コピペ一発でカスタマイズ出来るようにしてみました。

自作テーマからコードを切り出したので、少し冗長な部分もあるかもしれません。
スポンサーリンク
レクタングル(大)広告

Review構造化データ出力するカスタマイズ

レビュー用のJSON-LDを出力させるには、以下のコードをテーマ(子テーマ)のfunctions.phpにコピペしてください。

//チェックボックスの生成
if ( !function_exists( 'generate_checkbox_tag' ) ):
function generate_checkbox_tag($name, $now_value, $label){
  ob_start();?>
  <input type="checkbox" name="<?php echo $name; ?>" value="1"<?php the_checkbox_checked($now_value); ?>><?php echo $label; ?>
  <?php
  $res = ob_get_clean();
  echo $res;
}
endif;

//ラベルの生成
if ( !function_exists( 'generate_label_tag' ) ):
function generate_label_tag($name, $caption){?>
  <label for="<?php echo $name; ?>"><?php echo $caption; ?></label>
  <?php
}
endif;

//テキストボックスの生成
if ( !function_exists( 'generate_textbox_tag' ) ):
function generate_textbox_tag($name, $value, $placeholder){
  ob_start();?>
  <input type="text" name="<?php echo $name; ?>" style="width: 100%;" value="<?php echo esc_attr(strip_tags($value)); ?>" placeholder="<?php echo esc_attr($placeholder); ?>">
  <?php
  $res = ob_get_clean();
  echo $res;
}
endif;

//レンジボックスの生成
if ( !function_exists( 'generate_range_tag' ) ):
function generate_range_tag($name, $value, $min, $max, $step){
  ob_start();?>
  <div class="range-wrap" style="width: 100%;">
    <div class="range-value" style="text-align: center;margin-right: 1%;">
      <output id="<?php echo $name; ?>"><?php echo $value; ?></output>
    </div>
    <span class="range-min"><?php echo $min; ?></span><input type="range" name="<?php echo $name; ?>" value="<?php echo $value; ?>" min="<?php echo $min; ?>" max="<?php echo $max; ?>" step="<?php echo $step; ?>"
    oninput="document.getElementById('<?php echo $name; ?>').value=this.value" style="width: calc(100% - 18px);"><span class="range-min"><?php echo $max; ?></span>
  </div>
  <?php
  $res = ob_get_clean();
  echo $res;
}
endif;

//ハウツー説明文の生成
if ( !function_exists( 'generate_howro_tag' ) ):
function generate_howro_tag($caption){?>
  <p style="font-style: italic;"><?php echo $caption; ?></p>
  <?php
}
endif;

///////////////////////////////////////
// カスタムボックスの追加
///////////////////////////////////////
add_action('admin_menu', 'add_review_custom_box');
if ( !function_exists( 'add_review_custom_box' ) ):
function add_review_custom_box(){
  //レビュー
  add_meta_box( 'singular_review_settings', 'レビュー', 'review_custom_box_view', 'post', 'side' );
  add_meta_box( 'singular_review_settings', 'レビュー', 'review_custom_box_view', 'page', 'side' );
}
endif;

///////////////////////////////////////
// レビュー
///////////////////////////////////////
if ( !function_exists( 'review_custom_box_view' ) ):
function review_custom_box_view(){
  //レビュー切り替え
  $the_review_enable = is_the_review_enable();
  generate_checkbox_tag('the_review_enable' , $the_review_enable,  '評価を表示する');
  generate_howro_tag( 'レビュー構造化データを出力するか。');

  //対象
  $the_review_name = get_the_review_name();
  generate_label_tag('the_review_name', 'レビュー対象' );
  generate_textbox_tag('the_review_name', $the_review_name, '');
  generate_howro_tag( 'レビュー対象名を入力。※必須');

  //レート
  $the_review_rate = get_the_review_rate();
  if (!$the_review_rate) {
    $the_review_rate = 5;
  }
  generate_label_tag('the_review_rate', 'レビュー評価' );
  generate_range_tag('the_review_rate',$the_review_rate, 0, 5, 0.5);
  generate_howro_tag( '0から5の範囲で評価を入力。');

}
endif;

add_action('save_post', 'review_custom_box_save_data');
if ( !function_exists( 'review_custom_box_save_data' ) ):
function review_custom_box_save_data(){
  $id = get_the_ID();
  //有効/無効
  $the_review_enable = !empty($_POST['the_review_enable']) ? 1 : 0;
  $the_review_enable_key = 'the_review_enable';
  add_post_meta($id, $the_review_enable_key, $the_review_enable, true);
  update_post_meta($id, $the_review_enable_key, $the_review_enable);

  //名前
  if ( isset( $_POST['the_review_name'] ) ){
    $the_review_name = $_POST['the_review_name'];
    $the_review_name_key = 'the_review_name';
    add_post_meta($id, $the_review_name_key, $the_review_name, true);
    update_post_meta($id, $the_review_name_key, $the_review_name);
  }

  //レート
  if ( isset( $_POST['the_review_rate'] ) ){
    $the_review_rate = $_POST['the_review_rate'];
    $the_review_rate_key = 'the_review_rate';
    add_post_meta($id, $the_review_rate_key, $the_review_rate, true);
    update_post_meta($id, $the_review_rate_key, $the_review_rate);
  }
}
endif;

//名前
if ( !function_exists( 'get_the_review_name' ) ):
function get_the_review_name(){
  return trim(get_post_meta(get_the_ID(), 'the_review_name', true));
}
endif;

//レート
if ( !function_exists( 'get_the_review_rate' ) ):
function get_the_review_rate(){
  $res = get_post_meta(get_the_ID(), 'the_review_rate', true);
  $res = $res ? $res : '2.5'; //デフォルト値の設定
  return $res;
}
endif;

//レビューが有効か
if ( !function_exists( 'is_the_review_enable' ) ):
function is_the_review_enable(){
  return get_post_meta(get_the_ID(), 'the_review_enable', true);
}
endif;

//ページのレビューが有効か
if ( !function_exists( 'is_the_page_review_enable' ) ):
function is_the_page_review_enable(){
  return is_the_review_enable() && get_the_review_name();
}
endif;

//headにJSON-LDタグを追加
add_action( 'wp_head', 'add_review_json_ld_to_head' );
if ( !function_exists( 'add_review_json_ld_to_head' ) ):
function add_review_json_ld_to_head() {
  if (is_the_page_review_enable() && is_singular()) {
    //投稿者の取得(無い場合はサイト名)
    $author = get_the_author_meta('display_name');
    $author = $author ? $author : get_the_author_meta('nick_name');
    $author = $author ? $author : get_bloginfo( 'name' );
 ?>
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Review",
  "itemReviewed": {
    "@type": "Product",
    "name": "<?php echo esc_attr(get_the_review_name()); ?>",
    "review":{
      "author": {
      "@type": "Person"
      }
    }
  },
  "reviewRating": {
    "@type": "Rating",
    "ratingValue": "<?php echo esc_attr(get_the_review_rate()); ?>",
    "bestRating": "5",
    "worstRating": "0"
  },
  "datePublished": "<?php echo esc_attr(get_the_time('c')); ?>",
  "author": {
    "@type": "Person",
    "name": "<?php echo esc_attr($author); ?>"
  },
  "publisher": {
    "@type": "Organization",
    "name": "<?php echo esc_attr(get_bloginfo( 'name' )); ?>"
  }
}
</script>
  <?php
  }
}
endif;

入力フォーム作成用の関数を別に作って定義したりしているので、コードはちょっと長めです。

ただ、コピペするだけでJSON-LDをヘッダーに出力できるようになっているかと思います。

上記は、itemReviewedにProduct(製品・サービス)を設定した例です。その他の、レビュー構造化データ設定する場合は、対応しているschema typesを参照して独自にコードを付け足す必要がある場合もあります。
誤ったfunctions.phpの編集を行うと、画面が真っ白になってしまう恐れがあります。カスタマイズ前には、必ずfunctions.phpファイルをバックアップして、元に戻せる体制を整えておいてください。

参考 プラグインなしでGoogleの検索結果に星を表示する方法【コピペ】

公開ページに評価星を表示する方法

あと、できればテーマやプラグインなどで星を表示する機能があれば、公開ページでも同じ評価を星表示しておくと良いかもしれません。

ショートコードで星表示を行うカスタマイズ方法はこちら。

Amazonで商品を購入するときに僕は、ついつい星評価を見てしまいます。例えば「AとBの商品があり、どちらの性能も甲乙つけが...

コンテンツ内でも星表示をしておいた方が良いと思うのは、構造化データに関するガイドラインに以下のような記述があるからです。

ページの読者に表示されないコンテンツをマークアップしないでください。たとえば、JSON-LD マークアップでパフォーマーが記述されている場合、HTML の本文でも同じパフォーマーが記述されている必要があります。

上記の「パフォーマー」というのが、ちょっと何のことを指すのか分からない部分もあったのですが、表示させておくに越したことはないと思います。

テーマ等に星評価機能がなかったり、わざわざカスタマイズするのが面倒な場合は、以下のような星評価プラグインもあります。

Rating in the article with Dashicons.
USR provides shortcodes to give the author the opportunity to add ratings for desired products and services with the aid of a star rating system.

動作確認

星評価を行うには、投稿・固定ページの右サイドバーに「レビュー」という項目が表示されるので、そこで設定します。

エディターのレビュー項目

その際に以下の3点を入力してください。

エディターのレビュー項目で入力する項目

すると、以下のようにJSON-LD構造化データが出力されます。

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Review",
  "itemReviewed": {
    "@type": "Product",
    "name": "レンタルサーバー"
  },
  "reviewRating": {
    "@type": "Rating",
    "ratingValue": "4.5",
    "bestRating": "5",
    "worstRating": "0"
  },
  "datePublished": "2019-09-06T11:15:31+09:00",
  "author": {
    "@type": "Person",
    "name": "投稿者名"
  },
  "publisher": {
    "@type": "Organization",
    "name": "サイト名"
  }
}
</script>

構造化データチェックツールで見るとこんな感じ。

Review構造化データの出力

あと、本文中に星評価を読者の見えるところに記述しておけば良いかと思います(テーマのテンプレートファイルをカスタマイズして自動で表示するようにしても可)。

このように設定を行って、検索エンジンのクローラーに構造化データが認識され、表示が認められれば、以下のように「星評価」と「投稿者」情報が表示されます。

レビュー構造化データで星と投稿者を表示した場合

注意点

このカスタマイズは、以下の注意点を留意の上ご利用ください。

  • 投稿・固定ページのレビュー設定がしてない場合は表示されません
  • すぐに検索結果に反映されるわけではありません(数日~数週間以上かかる場合もあります)
  • レビュー設定をしたからといって必ずしも検索結果に星が表示されることは保証できません
  • Amazonに合わせて5段階評価までしかできない仕様です
  • 関連性のあるコンテンツで利用してください
  • 目立つからといって無闇やたらと使用することはおすすめしません(ペナルティーの恐れもあります)

構造化データ(リッチスニペット)については、以下をご一読しておくことをおすすめします。

知らずにやってしまっているかもしれないレビューのリッチスニペットのガイドラインに違反について説明する。ガイドライン違反が認められた場合は、手動の対策が与えられることがある。リッチスニペットが非表示になるかもしれない。
レビュー(Review)の構造化データ(schema.org)のマークアップ、実装例をご紹介。実装するとリッチリザルトとして平均評価(AggregateRating)などが表示されやすくなります。
Google 検索上の構造化データに関する一般的なガイドラインです。ガイドラインに順守することは構造化データがリッチリザルトとして検索結果に表示されやすくなることに役立ちます。

まとめ

このレビュー構造化データを設定することで、検索結果に星が表示されると、やはり目をひきます。

また、投稿者名も表示することができるので、名前を広く知られている方には、より効果を発揮するカスタマイズになるかと思います。

星と投稿者が表示されて目立つ

ただ、大事なことなので、何度も書きますが構造化データ(リッチスニペット)を無闇やたらに乱用するとペナルティの対象となりえます。

上でもリンクに挙げた、構造化データのガイドラインに準じてのご利用をおすすめします。

『検索結果に星評価を表示するWordPressカスタマイズ方法(JSON-LDでレビュー構造化データの出力)』へのコメント

  1. 名前:高橋健 投稿日:2019/10/18(金) 11:07:51 ID:b6112d150

    offers、review、aggregateRating のいずれかを指定する必要があります。

    というエラーがでてしまいます・・・

  2. アバター画像 名前:わいひら 投稿日:2019/10/18(金) 23:55:10 ID:a19d73c6e

    とりあえず、警告は出るけどエラーが出ないようには修正しておきました。