WordPress で OGP の情報を出力するには All in One SEO などのプラグインを使えば実現できるのですが、WordPress からしばらく離れていたこともあり WordPress 独特のプラグインが GitHub にない場合も多くスター数やどれが現段階でのベストプラクティスなの判断できない・セキュリティの問題がどうなっているのか判らないという事があり素振りも兼ねて自前で実装してみたのでメモ
OGP に必要なメタタグ
<head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# article: http://ogp.me/ns/article#">
<title>ページのタイトル</title>
<meta property="og:site_name" content="サイト名" />
<meta property="og:title" content="ページのタイトル" />
<meta property="og:type" content="ページの種類" />
<meta property="og:url" content="ページのURL" />
<meta property="og:image" content="サムネイル画像のURL" />
<meta property="og:description" content="ページのディスクリプション" />
<meta property="fb:app_id" content="App-ID(15文字の半角数字)" />
<meta name="twitter:card" content="Twitterカードの種類" />
cf. Facebook・TwitterのOGP設定方法まとめ|ferret
仕様
- WordPress:
v6.0
og:title
… 現在のページのタイトル
og:type
… website
, 投稿の場合は article
にする
og:url
… 現在のページの URL
og:image
… 投稿、固定ページでサムネイルがあればサムネイル。なければデフォルト画像。
og:site_name
… 固定値 (サイト名)
og:description
… 抜粋があれば抜粋。なければ本文から生成。それもなければデフォルト値
fb:app_id
… Facebook のアプリID なので固定値
twitter:card
… 投稿の時は summary
, 固定ページの場合は summary_large_image
※ コードを見やすくするために冗長に書いています
og:title
現在のページのタイトルを取得する
ページのタイトルを return する wp_get_document_title()
を使って取得する
固定値のサイト名は get_bloginfo('name')
で 管理画面 > 一般 > サイトのタイトル
に指定されている値にする
<?php
function mt_ogp() {
$siteName = get_bloginfo('name');
$title = wp_get_document_title();
$ogp = <<< EOM
<meta property="og:site_name" content="{$siteName}" />
<meta property="og:title" content="{$title}" />
EOM;
echo $ogp;
}
タイトル自体のカスタマイズは pre_get_document_title
のようなフィルターを使うことで head 内の title と og:title を同じにすることができる
cf.
og:type
ページのタイプ
website
, 投稿の場合は article
にする
is_singular()
は投稿ページ以外に固定ページ is_page()
, 添付ファイルページ is_attachment()
を含むので is_single()
を使うのが良さそう
<?php
function mt_ogp() {
$siteName = get_bloginfo('name');
$title = wp_get_document_title();
$pageType = 'website';
if ( is_single() ) {
$pageType = 'article';
}
$ogp = <<< EOM
<meta property="og:site_name" content="{$siteName}" />
<meta property="og:title" content="{$title}" />
<meta name="og:type" content="{$ogpType}">
EOM;
echo $ogp;
}
og:url
現在のページの URL
WordPress の URL は global の $post
などを使って取得することができるが、投稿がない場合やカテゴリーの投稿が 0 件の時 $post
が NULL
になったり、アーカイブページの $post
はアーカイブに含まれる最初の投稿だったりで分岐や条件分けがかなり複雑になってしまうので $_SERVER
を使って現在の URL を取得するようにした
<?php
function mt_ogp() {
$siteName = get_bloginfo('name');
$title = wp_get_document_title();
$pageType = 'website';
if ( is_single() ) {
$pageType = 'article';
}
$permalink = (is_ssl() ? 'https' : 'http') . '://' . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];
$ogp = <<< EOM
<meta property="og:site_name" content="{$siteName}" />
<meta property="og:title" content="{$title}" />
<meta name="og:type" content="{$ogpType}">
<meta property="og:url" content="{$permalink}" />
EOM;
echo $ogp;
}
og:image
投稿、固定ページでサムネイルがあればサムネイル。なければデフォルト画像。
サムネイルを設定できるページは is_singular()
(is_single()
+ is_page()
+ is_attachment()
) なので、これが true の時にサムネイルの有無をチェックする
サムネイル画像の URL は wp_get_attachment_image_src($attachment_id, $size);
で取得できる。デフォルトでは thumbnail
が取得されるので OGP なら large
か full
を指定すれば良さそう
<?php
define('OGP_IMAGE', get_home_url() . "/ogp.png");
function mt_ogp() {
global $post;
$siteName = get_bloginfo('name');
$title = wp_get_document_title();
$pageType = 'website';
if ( is_single() ) {
$pageType = 'article';
}
$permalink = (is_ssl() ? 'https' : 'http') . '://' . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];
$ogpImage = OGP_IMAGE;
if ( is_singular() ) {
$thumbnail = wp_get_attachment_image_src(
get_post_thumbnail_id($post->ID), 'full'
);
$ogpImage = $thumbnail[0] ?: OGP_IMAGE;
}
$ogp = <<< EOM
<meta property="og:site_name" content="{$siteName}" />
<meta property="og:title" content="{$title}" />
<meta name="og:type" content="{$ogpType}">
<meta property="og:url" content="{$permalink}" />
<meta property="og:image" content="{$ogpImage}" />
EOM;
echo $ogp;
}
cf. WordPress アップロードした画像を width, height 属性無しで取得したい - かもメモ
og:description
ディスクリプション
抜粋があれば抜粋。なければ本文から生成。それもなければデフォルト値
抜粋は global オブジェクトの $post から $post->post_excerpt
, 本文は $post->post_content
で取得できる。本文の場合はタグの除去を行う必要がある
アーカイブページや 404 ページ、検索結果などはデフォルト値を返すようにする
<?php
define("OGP_IMAGE", get_home_url() . "/ogp.png");
define("DESCRIPTION", "デフォルトのディスクリプション");
function get_my_descriptiom_by_post($post, $limit = 140, $more = '...') {
$summary = $post->post_excerpt;
if ( empty($summary) ) {
$content = apply_filters('the_content', $post->post_content);
$summary = strip_tags($content);
$summary = str_replace(array("\r\n","\n","\r"), ''
}
if ( empty($summary) ) { return NULL; }
$description = wp_trim_words($summary, $limit, $more);
return $description;
}
function mt_ogp() {
global $post;
$siteName = get_bloginfo('name');
$title = wp_get_document_title();
$pageType = 'website';
if ( is_single() ) {
$pageType = 'article';
}
$permalink = (is_ssl() ? 'https' : 'http') . '://' . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];
$ogpImage = OGP_IMAGE;
if ( is_singular() ) {
$thumbnail = wp_get_attachment_image_src(
get_post_thumbnail_id($post->ID), 'full'
);
$ogpImage = $thumbnail[0] ?: OGP_IMAGE;
}
$description = DESCRIPTION;
if ( is_singular() ) {
$description = get_my_descriptiom_by_post($post);
}
if ( empty($description) || empty($post) || is_404() ) {
$description = DESCRIPTION;
}
$ogp = <<< EOM
<meta property="og:site_name" content="{$siteName}" />
<meta property="og:title" content="{$title}" />
<meta name="og:type" content="{$ogpType}">
<meta property="og:url" content="{$permalink}" />
<meta property="og:image" content="{$ogpImage}" />
<meta property="og:description" content="{$description}" />
EOM;
echo $ogp;
}
fb:app_id
は Facebook で取得するアプリの ID なので固定値を使えば OK
twitter:card
は 投稿の時は summary
, 固定ページの場合は summary_large_image
にする
<?php
define("OGP_IMAGE", get_home_url() . "/ogp.png");
define("DESCRIPTION", "デフォルトのディスクリプション");
define("FACEBOOK_APP_ID", "APP ID");
function mt_ogp() {
global $post;
$siteName = get_bloginfo('name');
$title = wp_get_document_title();
$pageType = 'website';
if ( is_single() ) {
$pageType = 'article';
}
$permalink = (is_ssl() ? 'https' : 'http') . '://' . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];
$ogpImage = OGP_IMAGE;
if ( is_singular() ) {
$thumbnail = wp_get_attachment_image_src(
get_post_thumbnail_id($post->ID), 'full'
);
$ogpImage = $thumbnail[0] ?: OGP_IMAGE;
}
$description = DESCRIPTION;
if ( is_singular() ) {
$description = get_my_descriptiom_by_post($post);
}
if ( empty($description) || empty($post) || is_404() ) {
$description = DESCRIPTION;
}
$fbAppID = FACEBOOK_APP_ID;
$cardType = 'summary_large_image';
if ( is_single() ) {
$cardType = 'summary';
}
$ogp = <<< EOM
<meta property="og:site_name" content="{$siteName}" />
<meta property="og:title" content="{$title}" />
<meta name="og:type" content="{$ogpType}">
<meta property="og:url" content="{$permalink}" />
<meta property="og:image" content="{$ogpImage}" />
<meta property="og:description" content="{$description}" />
<meta property="fb:app_id" content={$fbAppID} />
<meta name="twitter:card" content="{$cardType}" />
EOM;
echo $ogp;
}
cf.
所管
なんとなくいい感じに OGP のメタタグを出力できるようになりました!
WordPress の全部を functions.php にマージして実行する仕組みにいまいち慣れない…
[参考]
おじP… ネタ切れ…