あるWP案件でOGPを設定した時の覚書

案件名を出せず肝心な部分を伏せているので何がなにやらごちゃついています。

マルチサイト構成のWordPressを使った某案件で設定した時の覚書です。
まずはさらっとOGPの説明から。

OGPとは

Open Graph Protcolの略でページの概要などをプログラムから読める形で記載するために仕様です。
詳しくは以下のページを参照してください。

今回追加したOGPは以下のものです。

<meta property="og:site_name" content="サイトの名前" />
<meta property="og:title" content="ページのタイトル" /> <!-- 必須らしい --/>
<meta property="og:url" content="ページのurl" /> <!-- 必須らしい --/>
<meta property="og:type" content="ページが何のページか記述" /> <!-- 必須らしい --/>
<meta property="og:description" content="ページ内容の説明" />
<meta property="og:image" content="ページが記述しているものの画像" /> <!-- 必須らしい --/>

上記OGPのうちog:title、og:url、og:type、og:imageは必須のようです。
これらを記述することでFacebookなどのSNSでリンクをシェアする場合、表示される情報をコントロールすることが出来ます。
また、XHTMLにOGPを設置する際はhtml要素にネームスペースを設定してやりましょう。

	<html xmlns:og="http://ogp.me/ns#">

こんな具合に…。設定するOGPによってネームスペースもいろいろな種類があるようなのでそれについても前述の参考サイトを参照してください。

WPサイトにOGPを組み込み

WP-OGPというプラグインもあるようですが、出力結果を完全にコントロールしたいのでコーディングしています。
このブログはVicunaテーマを使っていますが、テーマの機能なのかOGPがいい感じで反映されているようです。

マルチサイトで構築しており、トップページと配下のページ(トップレベルサイト)、ブログ1、ブログ2という構成になっています。

トップレベルサイト

トップページのサイトはトップページを含めすべてページ機能で実装しています。
このサイトはheader.phpをインクルードしているのでページのスラッグで分岐させています。
コードはこんな感じ。。

<meta property="og:site_name" content="サイトの名前" />
<?php if(is_front_page() && !is_page('スラッグ')) : ?>
<meta property="og:title" content="ページのタイトル" />
<meta property="og:url" content="ページのurl" />
<meta property="og:type" content="website" />
<meta property="og:description" content="ページ内容の説明" />
<meta property="og:image" content="ページが記述しているものの画像" />
<?php elseif(is_page('スラッグ')) : ?>
<meta property="og:title" content="ページのタイトル" />
<meta property="og:url" content="ページのurl" />
<meta property="og:type" content="article" />
<meta property="og:description" content="ページ内容の説明" />
<meta property="og:image" content="ページが記述しているものの画像" />
<?php elseif((is_front_page() && is_page('スラッグ')) || is_archive()) : ?>
<meta property="og:title" content="ページのタイトル" />
<meta property="og:url" content="ページのurl" />
<meta property="og:type" content="article" />
<meta property="og:description" content="ページ内容の説明" />
<meta property="og:image" content="ページが記述しているものの画像" />
<?php endif; ?>

サイト名は全ページ共通なので条件分岐の外に出しています。
トップページであるか、そのページのスラッグが何であるか・ないかで判定しているのですが、
一番下の条件式で引っかかるページがあるんだなあと感心しています。。

ここで注意が必要なのが、トップページのog:typeがwebsiteになっていて、その他のページはarticleになっています。
これは適切なものを指定しないと意図しないところに登録される可能性があるのでご注意を。)
また、いいねボタンを設置している場合は管理用ページを表示できるようですが、ブログ記事などの一時的なコンテンツをあらわすarticleでは見られない仕様のようです。

ブログ

ブログ1とブログ2はデザインが違うのテーマファイルを分けていますが、
構成はほぼ一緒なので書き込む内容はほぼ同じです。

シングルページ

パーマリンクのページで鬼門なのは、投稿にかならず1つ画像が添付されているので、
一番上に表示されている画像をog:imageに設定することでした。
それを実現したのが以下のソース。ググって解決したのでセキュアかどうか…。

<?php
$files = get_children("post_parent=$id&amp;post_type=attachment&amp;post_mime_type=image");
$img;
if (!empty($files)){
$keys = array_keys($files);
$lastkeys = array_pop($keys);
$num=$lastkeys;
$thumb=wp_get_attachment_image_src($num,'medium');
if ($thumb[0] != false) {
$img = $thumb[0];
}
}
?>
<meta property="og:site_name" content="サイトの名前" />
<meta property="og:title" content="<?php the_title();?> - サイトの名前" />
<meta property="og:url" content="<?php the_permalink(); ?>" />
<meta property="og:type" content="article" />
<meta property="og:description" content="<?php echo str_replace( "\n", "", mb_substr(get_the_excerpt(), 0, 100) ) ?>" />
<?php endwhile; endif; ?>
<?php if (empty($files)) : ?>
<meta property="og:image" content="画像のパス" />
<?php else : ?>
<meta property="og:image" content="<?php echo $img ?>" />
<?php endif ?>
get_children("post_parent=$id&post_type=attachment&post_mime_type=image");

上記のコードはこのページの子のファイルを取得するためのもので、ループの中で使わないといけません。
添付画像がある場合、一番最初に添付されたファイルを変数imgに代入しています。
今思うと、変数imgに画像のパスを代入して初期化しておいたほうがスマートだった気がしますね。。

アーカイブ、カテゴリページ

ブログサイトなのでアーカイブページ、カテゴリページにもOGPを入れていますが、それらのページでは常に同じ結果を返すためにPHPの処理はいれずに実装しています。

OGPのデバッグ

OGPをHTMLに埋め込んだら、デバッグをしましょう。Facebookが用意しているDebuggerというページで適切に反映できているか確認が出来ます。
また、公開後にOGPを入れた場合、OGPを入れる前にシェアされた情報はFacebook側でキャッシュを取られるようで、このツールを用いて保持されている情報を上書きしないとすぐにOGPの情報が反映されないので注意が必要です。
今、僕が個人的に制作中のうまうまっぷなるサイトで試すとこんな感じになります。

まとめ

以上、某案件でやったOGP対応です!このサイトはテーマファイルをあまり分割せずに作ってあったおかげで条件分岐がほとんどなくて楽でした。
もう1個僕が最初から最後まで作ったWP案件の場合は条件分岐が物凄いことになって大変でした…
余談ですが、分岐する場合は3つ以上の場合はswitchでそれ以下の場合はifで分岐させるほうがパフォーマンスが良いようですね…知らなかったのでコードをメンテナンスする際はそれに作り変えたいなと思っています。。僕の条件分岐ってif文ばっかりなので。。。