WordPressでTwitter Cardに対応してみた

Twitter Cardなる仕様を知った。TwitterでTweetに含まれる画像やYouTubeのリンクなんかがカードのように表示される機能には気づいていてTwitterが勝手に自動で表示しているだけと思っていたけど、FacebookのOpenGraphProtocolのようにメタタグを指定して通知することができるのがTwitter Card。対応するブログのリンクがつぶやかれると Twitter 上でこのように概要として表示される。

Twitter Card

Twitter Cards の設定項目

Documentation > Twitter Cards にドキュメントがある。カードには画像や動画などいくつか種類があるようでブログの投稿(文章)であれば summary タイプを選ぶ。

summary-cardに設定するプロパティは以下のようなものがある。
https://dev.twitter.com/docs/cards/types/summary-card

カードプロパティ 詳細 必須かどうか
twitter:card カードの種類、summaryを設定する 必須ではない(デフォルトがsummaryなので)
twitter:title タイトル(70文字) 必須
twitter:description 要約(200文字) 必須
twitter:image:src 画像URL(120×120は縮小されたり、60×60以下だと表示されないかも) 必須じゃない

なお、title, description, imageなどはOGPのメタデータがあればそれを代用してれるらしい。これに加えて以下のような共通プロパティがある。

カードプロパティ 詳細
twitter:site カードのフッタに表示されるサイトの@username
twitter:site:id twitter:siteのID版、@usernameと違ってIDは変わらないというメリット
twitter:creator コンテンツの作者の@username
twitter:creator:id twitter:creatorのID版
twitter:domain フッタに表示される

画像をみると誰のアカウントのCardか、この内容はどのdomainで見れるかなどを合わせて表示できるようだ。

@screen_nameを変える気はあまりないのでidではなく@screen_nameを使う。こんな感じのコードをWP_OGP_TWITTER*の値を適宜設定してテーマのheader.phpの <head>〜</head>の間に入れる。サムネイルは最初の画像リンクを使い、なければテーマのディレクトリの/images/ogp_default.pngを使う。抜き出すと以下のような実装になる。

<?php
define('WP_OGP_POST_DESCRIPTION_KEY', 'description');
define('WP_OGP_POST_IMAGE_SIZE', 'medium');
define('WP_OGP_DEFAULT_IMG', get_template_directory_uri() .'/images/ogp_default.png');

// Twitter Usernames
define('WP_OGP_TWITTER_SITE_USERNAME', '@site_username');
define('WP_OGP_TWITTER_CREATOR_USERNAME', '@creator_username');
define('WP_OGP_TWITTER_DOMAIN', 'YourDomain.com');

function ogp_post_description() {
    global $post;
    $description = null;
    if (defined('WP_OGP_POST_DESCRIPTION_KEY')) {
        $description = get_post_meta($post->ID, WP_OGP_POST_DESCRIPTION_KEY, true);
    }
    if (empty($description)) {
        $description = get_the_excerpt();
    }
    return $description;
}
function ogp_post_image() {
    $image = null;
    if ($image_id = get_post_thumbnail_id()) {
        $image = wp_get_attachment_image_src($image_id, WP_OGP_POST_IMAGE_SIZE);
    }
    if (empty($image)) {
        // find first img element
        global $post;
        if (preg_match('/<img[^>]*src\s*=\s*("|\')([^"\']+)("|\')[^>]*>/i', $post->post_content, $matches)) {
            return $matches[2];
        }
    }
    return $image;
}?>
<?php if( is_single() || is_page()): ?>
<?php while(have_posts()): the_post(); ?>
<meta name="twitter:card" content="summary" />
<meta name="twitter:title" content="<?php echo mb_strimwidth(get_the_title(), 0, 70, '...'); ?>" />
<?php if ($og_description):?>
<meta name="twitter:description" content="<?php echo mb_strimwidth(esc_attr($og_description), 0, 200); ?>" />
<?php endif; ?>
<?php if ($og_description = ogp_post_description()):?>
<meta name="twitter:image:src" content="<?php echo $og_image ?>" />
<?php else: ?>
<meta name="twitter:image:src" content="<?php echo WP_OGP_DEFAULT_IMG ?>" />
<?php endif; ?>
<?php if (defined('WP_OGP_TWITTER_SITE_USERNAME')): ?>
<meta name="twitter:site" content="<?php echo WP_OGP_TWITTER_SITE_USERNAME; ?>" />
<?php endif ?>
<?php if (defined('WP_OGP_TWITTER_CREATOR_USERNAME')): ?>
<meta name="twitter:creator" content="<?php echo WP_OGP_TWITTER_CREATOR_USERNAME; ?>" />
<?php endif ?>
<?php if (defined('WP_OGP_TWITTER_DOMAIN')): ?>
<meta name="twitter:domain" content="<?php echo WP_OGP_TWITTER_DOMAIN; ?>" />
<?php endif ?>
<?php endwhile; ?>

このブログではFacebook向けの設定も含めて使っているので以下のファイルあたりが参考になります。
header.php
header_ogp.php

対応は簡単なので誰かがプラグインを作っているかもしれません。探してみると良いかと。

検証と承認

ブログに設定したらCard Validator を開き、Summaryをカタログから選択。

Validate & Apply のタブを開いて適当な投稿のURLを設定。Server Errorと表示されることもあるけど何度かやっていると成功した。

キャプチャを撮りそこねたが、最初 blog.makotokw.com はまだ Apploval じゃないと赤い文字が出たのでそこにあったリンクからドメインの情報を入力した。どうやらdomain単位でCardを許可するかどうかTwitter側が制限しているようだ。

ドメインの必要な情報はCardプロパティをベースにほとんど埋まっていたのでサイトの所有者に自分のtwitter名を入れてサイトのdescriptionにmakoto_kw’s blogと入れて登録したらすぐにメールが来て承認された。