WordPressにプラグインなしでOGP設定

プラグインなしでOGP設定
プラグインなしでOGP設定

今更な内容ですが、WordPressにプラグインなしでOGP設定する方法に関する内容です。

当ブログにOGPを付け忘れていたので以前のものを使おうと思ったのですが、今見るといろいろ微妙な部分もあったため作り直しました。

descriptionの部分などで難儀したので、メモを残す意味でも記事にしたいと思います。

実現したいこと

実現したいことは以下の通り。

  • プラグイン無しでOGP設定
  • Twitter Twitter Cardsも設定

基本的な部分なので、プラグインに頼らない実装を目論みます。

構造

今回は以下のような構造にしました。

  • OGP用に関数を作成
  • 各場所にその関数を記述することで内容を表示

OGPに関連するファイルが増えてしまうのですが、一つにまとめて分岐などを書いているとゴチャゴチャしすぎたので、思い切って分けた次第です。

そのため、コードはheader.phpfunctions.phpに分けています。

コード

早速コードを。まずはメインとなるfunctions.phpに記載する関数から。


//抜粋をループ外で使用
function out_of_loop_excerpt(){
  global $post;
  $text ='';
  //文字数制限
  $length = 100;

  $content = $post->post_content;
  $excerpt = $post->post_excerpt;

  if(!$excerpt){
  //抜粋欄に内容がない場合
    $text = strip_tags($content);
    $text = strip_shortcodes($text);
    $text = preg_replace('#<img (.*?)>#i', '', $text);
    $text = str_replace(array("\r\n","\r","\n"), '', $text);
  } else {
  //抜粋欄に内容がある場合
    $text = strip_tags($excerpt);
  }

  if(mb_strlen($text) > $length){
    $text = mb_substr($text, 0, $length);
    echo $text . '...';
  } else {
    echo $text;
  }

}
//ogp用
function ogp_url(){
  $url = '';
  if(is_front_page()) {
    if(!in_the_loop()){//TOPページのループ外なら
      $url = get_home_url();
    } else {//TOPページのループ内なら
      $url = get_the_permalink();
    }
  } elseif (is_archive()){
    if(!in_the_loop()){//アーカイブのループ外なら
      if(empty($_SERVER['HTTPS'])){
        $url = 'http://'. $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];
      } else {
        $url = 'https://'. $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];
      }
    } else {//アーカイブのループ内なら
      $url = get_the_permalink();
    }
  } else {//それ以外の投稿ページや固定ページなど
    $url = get_the_permalink();
  }
  echo esc_url($url);
}
function ogp_title(){
  $title = '';
  if(is_front_page()) {
    $title = get_bloginfo('name');
  } elseif(is_archive()){
    $title = get_the_archive_title().' | '.get_bloginfo('name');
  } else {//それ以外の投稿ページや固定ページなど
    $title = get_the_title().' | '.get_bloginfo('name');
  }
  echo esc_html($title);
}
function ogp_description(){
 $description = '';
  if(is_singular()){
    $description = out_of_loop_excerpt();
  } else {
    $description = bloginfo('description');
  }
  echo esc_html($description);
}
function ogp_image(){
  $imgUrl = '';
  $stylesheet_dir = get_stylesheet_directory_uri();
  $default = $stylesheet_dir.'/images/ogp-img.png';
  if(is_singular()){
    global $post;
    if(has_post_thumbnail()){
      //アイキャッチがある場合
      $image_id = get_post_thumbnail_id();
      $image = wp_get_attachment_image_src($image_id, 'full');
      $imgUrl = $image[0];

    } elseif(preg_match_all('/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $post->post_content, $matches)) {
      //アイキャッチがない場合で、最初の画像がある場合
      //最初の画像のURLを取得
      $imgUrl = $matches[1][0];
      //サイトのURLを取得
      $site_url = esc_url( home_url());

      if(strpos($imgUrl, $site_url) !== false ){
        //最初の画像のURL内にサイトのURLと同じ文字列があれば、それを設定
        $imgUrl = $imgUrl;
      } else {
         //最初の画像のURL内にサイトのURLと同じ文字列がなければ、デフォルト画像を設定
        $imgUrl = $default;
      }
    } else {
      //アイキャッチも最初の画像もない
      $imgUrl = $default;
    }
  } else {
    //ホーム・カテゴリーページなど
    $imgUrl = $default;
  }
  echo esc_url($imgUrl);
}
function ogp_type(){
 $type = '';
  if(is_singular()){
    $type = 'article';
  } else {
    $type = 'website';
  }
  echo $type;
}

descriptionは、WordPressにデフォルトでついている抜粋機能を利用している場合、その抜粋の内容の方を表示するようにしています。

最初の画像を探す際に広告の画像がヒットする可能性もあるため、サイトのURLを取得して分岐条件に用いています。

続いてheader.phpに記載するOGP側ですが、項目は必須でないものも含まれています。


<meta property='og:locale' content='ja_JP'>
<meta property='og:type' content='<?php ogp_type(); ?>'>
<meta property='og:url' content='<?php ogp_url(); ?>'>

<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="twitterアカウント名">
<meta name="twitter:domain" content="<?php echo get_home_url();" />
<meta name="twitter:title" content="<?php ogp_title(); ?>">
<meta name="twitter:description" content="<?php ogp_description(); ?>">
<meta name="twitter:image:src" content="<?php ogp_image(); ?>">
<meta name="twitter:image:url" content="<?php ogp_url(); ?>">

これで表示できると思います。

ループ外で表示可能な抜粋

抜粋を表示させるthe_excerpt()は、ループの中で使うためのテンプレートタグです。

これをheadなどのループ外で用いるには、少し工夫が必要になります。

調べると、以下のページに情報が記載されていました。

ただ、このままでは以下の問題がありました。

  • 記事冒頭に画像がある場合、画像のimgタグやショートコードのcaptionが取得される
  • 今回は投稿画面の抜粋欄に記述がある場合は、抜粋の方を表示させたい

そこで、以下のように作り替えた次第です。


//抜粋をループ外で使用
function out_of_loop_excerpt(){
  global $post;
  $text ='';
  //文字数制限
  $length = 100;

  $content = $post->post_content;
  $excerpt = $post->post_excerpt;

  if(!$excerpt){
  //抜粋欄に内容がない場合
    $text = strip_tags($content);
    $text = strip_shortcodes($text);
    $text = preg_replace('#<img (.*?)>#i', '', $text);
    $text = str_replace(array("\r\n","\r","\n"), '', $text);
  } else {
  //抜粋欄に内容がある場合
    $text = strip_tags($excerpt);
  }

  if(mb_strlen($text) > $length){
    //最大文字数以上なら三点リーダー追加
    $text = mb_substr($text, 0, $length);
    echo $text . '...';
  } else {
    echo $text;
  }

}

今回の記事ではOGP設定が目的でしたが、metadescriptionにも使っています。

参考サイト

参考サイトは以下の通りです。

結び

以前の設定を流用した部分は楽でしたが、descriptionの部分を以前とは違うやり方に変えたためか、上手くいかず想定外に時間がかかってしまいました。

プラグインを使えば楽ですし、使わない選択肢を選ぶ必要性はあまりないと思うのですが、今回は以下のようなメリットもありました。

  • 抜粋文の有無による分岐の作成
  • 各項目内容の微調整
  • ループ内外の動作の再確認
  • metadescriptionにも使える

パンくずほどでは無いにせよ、多少は復習できた気がしますので、まぁよかったかなと。

0人がこの記事を評価

役に立ったよという方は上の「記事を評価する」ボタンをクリックしてもらえると嬉しいです。

連投防止のためにCookie使用。SNSへの投稿など他サービスとの連動は一切ありません。

コメント欄