WordPress Logo WordPress で OGP を設定

WordPress でプラグインを使わずに OGP を設定するする方法につていの覚書です。

更新日:2023年06月09日

作成日:2023年6月9日

OGP の設定

OGP を設定するには prefix 属性で OGP の使用を宣言し、head タグ内で meta タグを使ってメタデータを記述します。この例では、以下のような属性やタグを functions.php を使って出力します。

prefix 属性は <html> に出力します。

<html prefix="og: https://ogp.me/ns#">

そして <head> 内に以下のタグを出力します。

<!-- 基本的な OGP メタデータ(必須) -->
<meta property="og:type" content="ページの種類">
<meta property="og:url" content="ページの URL">
<meta property="og:title" content="ページのタイトル">
<meta property="og:image" content="ページの画像のURL">
<!-- オプションの OGP メタデータ -->
<meta property="og:description" content="ページの説明">
<meta property="og:site_name" content="サイト名">
<meta property="og:locale" content="言語の指定">
<!-- Facebook 用メタデータ -->
<meta property="fb:app_id" content="アプリID">
<!-- Twitter 用メタデータ -->
<meta name="twitter:card" content="カードタイプ">
<meta name="twitter:site" content="ウェブサイトの@ユーザー名">

OGP の基本的な設定については以下を御覧ください。

WordPress で OGP タグを出力

functions.php にコードを記述して prefix 属性を <html> に追加し、上記のような meta タグを <head> タグ内に出力します。

prefix 属性

prefix 属性は、html タグまたは head タグに設定することができます。

この例では、<html> タグに lang 属性を出力する language_attributes() のフィルターフック language_attributes を利用して、lang 属性の後に続けて prefix 属性を出力します。

そのため、前提として header.php などのテンプレートで以下のように language_attributes() が設定されている必要があります。

header.php 抜粋
<html <?php language_attributes(); ?>>

prefix 属性を html タグに追加するには、以下を functions.php に記述します。

functions.php
function add_ogp_prefix_to_language_attributes($output) {
  // lang 属性の後に prefix 属性 を追加
  return $output . ' prefix="og: https://ogp.me/ns#"';
}
add_filter('language_attributes', 'add_ogp_prefix_to_language_attributes');

上記により、<html> は例えば以下のように出力されます。

<html lang="ja" prefix="og: https://ogp.me/ns#">

meta タグの出力

以下の例では、投稿(及びカスタム投稿タイプ)の個別ページや固定ページ、トップページで OGP のタグを出力します。それ以外のカテゴリーページなどでは出力しません。

functions.php にコードを記述して、property や name 属性に以下のような値を設定した meta タグを <head> タグ内に出力します。

property content(値)
og:type トップページでは website、それ以外のページでは article を設定
og:url ページの URL。この例では $_SERVER(環境変数)を使って URL を生成しています。個別ページでは get_permalink() を使い、トップページでは home_url() を使っても取得できます。
og:title ページのタイトル。個別ページでは $post->post_title から取得し、トップページでは get_bloginfo('name') の値を出力しています。トップページの場合、初期値の設定で変数 $ogp_title に値を設定すれば、その値を代わりに出力します。
og:image 画像の URL。アイキャッチ画像が設定されていれば wp_get_attachment_image_src() でそのフルサイズの画像の URL を取得して出力します。アイキャッチ画像が設定されていない場合は、デフォルト画像の URL を出力します。デフォルト画像の URL は初期値の設定で変数 $ogp_image に設定します。
og:description ページの説明文。個別ページでは $post->post_excerpt で抜粋を取得して表示します。抜粋が設定されていない場合は、本文から80文字を取得して表示します。トップページでは get_bloginfo('description') の値を出力しています。トップページの場合、初期値の設定で変数 $ogp_description に値を設定すれば、その値を代わりに出力します。
og:site_name サイト名。get_bloginfo('name') を出力します。初期値の設定で変数 $ogp_site_name に値を設定すれば、その値を代わりに出力します。
og:locale ページの言語。get_locale() の値を出力します。初期値の設定で変数 $ogp_locale に値を設定すれば、その値を代わりに出力します。日本語の場合、get_locale() で取得される値は 'ja' になるので、この例では初期値の設定で $ogp_locale = 'ja_JP' としています。
fb:app_id Facebook アプリ ID。初期値の設定で変数 $fb_app_id に値を設定すれば property="fb:app_id" の meta タグを出力します。
name content(値)
twitter:card Twitter カードの種類。初期値の設定で変数 $twitter_card_type に summary_large_image または summary などのカードタイプを設定します。
twitter:site Web サイト単位で使用している Twitter の @ユーザー名。初期値の設定で変数 $twitter_site_username に値を設定すれば、name="twitter:site" の meta タグを出力します。

ページのタイトルは個別ページでは $post->post_title から取得し、トップページでは get_bloginfo('name') の値を出力しています。

また、サイト名は全てに共通で get_bloginfo('name') の値を使用しているので、トップページではページのタイトルとサイト名が同じ値になります。

トップページの説明文は get_bloginfo('description') を使用しているので、キャッチフレーズが設定されていない場合は、トップページの説明文が空になります。

必要に応じて、初期値の設定でトップページのタイトルや説明文を別途設定することができます。また、サイト名も初期値の設定で変数に指定すれば、その値が使用されます。

31行目の個別ページのタイトルの取得では、ループ外で記事のタイトルを取得する single_post_title() を使用しています。single_post_title() の代わりに $post->post_title を使っても同じです。

single_post_title() で取得したタイトルの文字列から stripslashes() でクォートされた文字列のクォート部分を取り除き、またタグが含まれている可能性があるので、wp_strip_all_tags() でタグを除去しています。

説明文に設定する抜粋も同様に wp_strip_all_tags() でタグを除去し、コンテンツから抽出した場合は、改行を半角スペースに変換しています。

また、meta タグの content 属性に取得した値を設定する際は、esc_attr()esc_url() を使ってエスケープ処理をします。

function add_ogp_metas() {
  // 投稿の個別ページや固定ページ、トップページであれば
  if (is_front_page() || is_home() || is_single() || is_page()) {
    global $post;
    // ページタイプ
    $ogp_type = 'website';
    // ページの URL
    $ogp_url = '';
    // ページのタイトル(トップページでは以下で指定すればその値を)
    $ogp_title = '';
    // ページの説明文(トップページでは以下で指定すればその値を)
    $ogp_description = '';
    // デフォルト画像の URL (アイキャッチ画像がない場合に使用)
    $ogp_image = 'デフォルト画像のURL';
    // サイト名(以下で指定すればその値を、空の場合は  get_bloginfo('name') の値)
    $ogp_site_name = '';
    // サイトの言語(以下で指定すればその値を、空の場合は get_locale() の値)
    $ogp_locale = 'ja_JP';
    // Twitter カードの種類(summary_large_image または summary を指定)
    $twitter_card_type = 'summary_large_image';
    // Twitter の @ユーザー名(指定すれば twitter:site のタグを出力)
    $twitter_site_username = '';
    // Facebook アプリ ID(指定すれば fb:app_id のタグを出力)
    $fb_app_id = '';
    // 出力する meta タグ
    $ogp = '';

    // 個別ページの場合はページタイプを article に
    if (is_singular()) {
      $ogp_type = 'article';
      $ogp_title = wp_strip_all_tags(stripslashes(single_post_title('', false)), true);
      // 抜粋を取得
      $excerpt = wp_strip_all_tags($post->post_excerpt);
      // 抜粋が設定されていなければコンテンツから抽出
      if (empty($excerpt)) {
        // HTML タグを削除
        $excerpt = wp_strip_all_tags($post->post_content);
        // 改行を半角スペースに変換
        $excerpt = str_replace(array("\r\n", "\n", "\r"), ' ', $excerpt);
      }
      // 80 文字に
      $ogp_description = wp_trim_words($excerpt, 80, '...');

      // アイキャッチ画像があれば
      if (has_post_thumbnail()) {
        $thumbnail_src = wp_get_attachment_image_src(get_post_thumbnail_id($post->ID), 'full');
        // $thumbnail_src[0] は画像の URL
        if ($thumbnail_src && $thumbnail_src[0]) {
          $ogp_image = $thumbnail_src[0];
        }
      }
    } elseif (is_front_page() || is_home()) { //トップページ
      if (empty($ogp_title)) {
        $ogp_title = get_bloginfo('name');
      }
      if (empty($ogp_description)) {
        $ogp_description = get_bloginfo('description');
      }
    }

    // ページの URL
    $ogp_url =  (empty($_SERVER['HTTPS']) ? 'http://' : 'https://') . $_SERVER['HTTP_HOST'] . $_SERVER["REQUEST_URI"];

    // サイト名(初期値が設定されていなければ get_bloginfo('name') の値を設定)
    if (empty($ogp_site_name)) {
      $ogp_site_name = get_bloginfo('name');
    }

    // サイトの言語(初期値が設定されていなければ get_locale() の値を設定)
    if (empty($ogp_locale)) {
      $ogp_locale = get_locale();
    }

    // 出力する meta タグを生成
    $ogp = "\n";
    $ogp .= '<meta property="og:type" content="'.$ogp_type.'">'."\n";
    $ogp .= '<meta property="og:url" content="'.esc_url($ogp_url).'">'."\n";
    $ogp .= '<meta property="og:title" content="'.esc_attr($ogp_title).'">'."\n";
    $ogp .= '<meta property="og:description" content="'.esc_attr($ogp_description).'">'."\n";
    $ogp .= '<meta property="og:image" content="'.esc_url($ogp_image).'">'."\n";
    $ogp .= '<meta property="og:site_name" content="'.esc_attr($ogp_site_name).'">'."\n";
    $ogp .= '<meta property="og:locale" content="'.esc_attr($ogp_locale).'">'."\n";
    $ogp .= '<meta name="twitter:card" content="'.$twitter_card_type.'">'."\n";
    // $twitter_site_username に値が設定されていれば
    if (!empty($twitter_site_username)) {
      $ogp .= '<meta name="twitter:site" content="'.$twitter_site_username.'">'."\n";
    }
    // $fb_app_id に値が設定されていれば
    if (!empty($fb_app_id)) {
      $ogp .= '<meta property="fb:app_id" content="'.$fb_app_id.'">'."\n";
    }
    // meta タグを出力
    echo $ogp;
  }
}
add_action('wp_head', 'add_ogp_metas');

上記の関数 add_ogp_metas で生成した meta タグは wp_head アクションにフックして head タグ内に出力しています。

例えば、以下のような meta タグが出力されます。

<meta property="og:type" content="article">
<meta property="og:url" content="http://localhost/wp/2023/06/08/my-first-post/">
<meta property="og:title" content="My First Post">
<meta property="og:description" content="これは最初の投稿です。OGP のテストです。">
<meta property="og:image" content="http://localhost/wp/wp-content/uploads/2023/06/01.jpg">
<meta property="og:site_name" content="My WordPress">
<meta property="og:locale" content="ja_JP">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@username">
<meta property="fb:app_id" content="123456789012345">
URL の生成($_SERVER['HTTPS'])

上記の例では、ページの URL は $_SERVER['HTTPS'] の値で http か https を判定していますが、値を返さないサーバーもあるので、必要に応じて以下を記述しておきます。

// 値を返さないサーバーで、SSL化されいる場合は $_SERVER['HTTPS'] に 'on' を設定
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) and $_SERVER['HTTP_X_FORWARDED_PROTO'] === "https") {
  $_SERVER['HTTPS'] = 'on';
}

または、個別ページでは get_permalink() を使い、トップページでは home_url() を使ってページの URL を取得することもできます。

ページのタイトル

この例では個別ページのタイトルは $post->post_title から取得し、トップページのタイトルは get_bloginfo('name') の値を出力しています。

add_theme_support( 'title-tag' ) を functions.php に記述することで wp_get_document_title() によりページの種類に応じて <title> タグが <head> 内に自動的に出力されるので、その値を使ってタイトルを指定することもできます。

// ページのタイトル
$ogp_title = wp_get_document_title();

ページの種類で分岐せずに上記だけでタイトルを設定できますが、デフォルトで生成されるタイトルには「ページのタイトル – サイト名」のようにサイト名が含まれ、またフロントページでは「サイト名 – キャッチフレーズ」のようになります。

pre_get_document_title や document_title_separator などを使って自動生成されるタイトルをカスタマイズすることもできます。

関連ページ:WordPress title タグの出力

カテゴリーやタグ一覧でも OGP を出力

以下はカテゴリーやタグ一覧でも OGP を出力するようにした例です。前述のコードに対象のテンプレートの条件の追加(14行目)と51〜75行目の部分を追加しただけです。

カテゴリーやタグページの説明文は、それぞれのカテゴリーやタグに説明が設定されていればその値を出力し、設定されていなければ、「カテゴリー: xxxx の一覧」のようなテキストを出力するようにしています。

また、カテゴリーやタグページの画像はデフォルトの画像の URL が出力されます。

//$_SERVER['HTTPS'] が値を返さないサーバー対策
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) and $_SERVER['HTTP_X_FORWARDED_PROTO'] === "https") {
  $_SERVER['HTTPS'] = 'on';
}

// prefix 属性を html 要素に追加
function add_ogp_prefix_to_language_attributes($output) {
  return $output . ' prefix="og: https://ogp.me/ns#"';
}
add_filter('language_attributes', 'add_ogp_prefix_to_language_attributes');

// OGP のタグを出力する関数
function add_ogp_metas() {
  if (is_front_page() || is_home() || is_single() || is_page() || is_category() || is_tag() || is_tax()) {
    global $post;
    $ogp_type = 'website';
    $ogp_url = '';
    $ogp_title = '';
    $ogp_description = '';
    $ogp_image = 'デフォルト画像のURL';
    $ogp_site_name = '';
    $ogp_locale = 'ja_JP';
    $twitter_card_type = 'summary_large_image';
    $twitter_site_username = '@username';
    $fb_app_id = '123456789012345';
    $ogp = '';

    if (is_singular()) {
      $ogp_type = 'article';
      $ogp_title = wp_strip_all_tags(stripslashes(single_post_title('', false)), true);
      $excerpt = wp_strip_all_tags($post->post_excerpt);
      if (empty($excerpt)) {
        $excerpt = wp_strip_all_tags($post->post_content);
        $excerpt = str_replace(array("\r\n", "\n", "\r"), ' ', $excerpt);
      }
      $ogp_description = wp_trim_words($excerpt, 80, '...');

      if (has_post_thumbnail()) {
        $thumbnail_src = wp_get_attachment_image_src(get_post_thumbnail_id($post->ID), 'full');
        if ($thumbnail_src && $thumbnail_src[0]) {
          $ogp_image = $thumbnail_src[0];
        }
      }
    } elseif (is_front_page() || is_home()) {
      if (empty($ogp_title)) {
        $ogp_title = get_bloginfo('name');
      }
      if (empty($ogp_description)) {
        $ogp_description = get_bloginfo('description');
      }
    } elseif (is_category()) {  // カテゴリー一覧の場合を追加
      $ogp_title = wp_strip_all_tags(stripslashes(single_cat_title('', false)), true);
      $cat_description = trim(wp_strip_all_tags(stripslashes(category_description()), true));
      if (!empty($cat_description)) {
        $ogp_description = $cat_description;
      } else {
        $ogp_description = 'カテゴリー: '.$ogp_title .' の一覧';
      }
    } elseif (is_tag()) {  // タグ一覧の場合を追加
      $ogp_title = wp_strip_all_tags(stripslashes(single_tag_title('', false)), true);
      $tag_description = trim(wp_strip_all_tags(stripslashes(tag_description()), true));
      if (!empty($tag_description)) {
        $ogp_description = $tag_description;
      } else {
        $ogp_description = 'タグ: '.$ogp_title.'の一覧';
      }
    } elseif (is_tax()) {  // タクソノミー一覧の場合を追加
      $ogp_title = wp_strip_all_tags(stripslashes(single_term_title('', false)), true);
      $tax_description = trim(wp_strip_all_tags(stripslashes(term_description()), true));
      if (!empty($tax_description)) {
        $ogp_description = $tax_description;
      } else {
        $ogp_description = $ogp_title.'の一覧';
      }
    }

    $ogp_url =  (empty($_SERVER['HTTPS']) ? 'http://' : 'https://').$_SERVER['HTTP_HOST'].$_SERVER["REQUEST_URI"];

    if (empty($ogp_site_name)) {
      $ogp_site_name = get_bloginfo('name');
    }

    if (empty($ogp_locale)) {
      $ogp_locale = get_locale();
    }

    $ogp = "\n";
    $ogp .= '<meta property="og:type" content="'.$ogp_type.'">'."\n";
    $ogp .= '<meta property="og:url" content="'.esc_url($ogp_url).'">'."\n";
    $ogp .= '<meta property="og:title" content="'.esc_attr($ogp_title).'">'."\n";
    $ogp .= '<meta property="og:description" content="'.esc_attr($ogp_description).'">'."\n";
    $ogp .= '<meta property="og:image" content="'.esc_url($ogp_image).'">'."\n";
    $ogp .= '<meta property="og:site_name" content="'.esc_attr($ogp_site_name).'">'."\n";
    $ogp .= '<meta property="og:locale" content="'.esc_attr($ogp_locale).'">'."\n";
    $ogp .= '<meta name="twitter:card" content="'.$twitter_card_type.'">'."\n";

    if (!empty($twitter_site_username)) {
      $ogp .= '<meta name="twitter:site" content="'.$twitter_site_username.'">'."\n";
    }
    if (!empty($fb_app_id)) {
      $ogp .= '<meta property="fb:app_id" content="'.$fb_app_id.'">'."\n";
    }
    echo $ogp;
  }
}
add_action('wp_head', 'add_ogp_metas');