WebNAUT

AMPが当たり前の時代なのでWordPressのオリジナルテーマをAMP対応させてみた

※この記事は2017年1月16日に執筆された記事です。現在は仕様が異なる可能性があります。


技術の移り変わりの早さに翻弄されているエンジニアの皆さんこんにちは!

先日のWebNAUTリニューアルの目玉のひとつとして「AMP対応」というものがありましたが、今回はそれを例に、「WordPressのオリジナルテーマを、プラグインをうまいこと使ってAMP対応させてみよう」というテーマで記事を書いてみました。

AMPとは?

AMP(Accelerated Mobile Page)とは、GoogleなどのCDNにページの情報がキャッシュとして保持され、検索からのページ訪問の際にびっくりするほど表示が早くなるという夢のような技術です。

下の画像のように、検索結果ページのディスクリプション領域に、「⚡️AMP」の表記があるのがAMPページです。最近よく見るようになりましたね。

AMP対応させるには、通常のhtmlタグの記述とは異なる「AMPタグ」なるものを適宜使用しなくてはならないことに加え、例えば下記のような制約があります。

上記含めた諸々のAMPルールをクリアすると、Googleのクロールの際にAMPページとしてインデックスされ、晴れて検索結果に稲妻マーク⚡️付きのページが表示されるわけですね。

全体のルールはAMP Projectのサイトに載っているので、そちらを見てみてください。

WordPressのAMP化は?

いまご覧いただいているWebNAUTはCMSとしてWordPressを使用しているのですが、WordPressのAMP対応にはプラグインが便利です。

AMPーWordPress Plugins

Automatic社製の公式プラグインなので安心ですね。

ただ、このプラグインを有効化させただけだと、こんな風にこれ以上ないデフォルト感漂うサイトとなってしまいます。

これは、wp-content/plugins/amp/theme内のテーマが適用されてしまうためです。

さすがにこれで「AMP対応しました!」とは言えないので、AMPページであっても通常のスマホページと同じ見え方となるように手を加えていきましょう。

やり方としては、

の2パターンが考えられましたが、今回は通常ページとAMPページでデザインは統一するということもあり、保守性を考慮して後者を選択しました。

WebNAUTのwp-content/theme内の構造としては、このような感じになっています。(分かりやすいように一部を省略、並び順も変更しています)

theme
  ├pc
  │ ├...
  │
  └sp
    ├functions.php
    ├header.php
    ├footer.php
    ├index.php
    ├single.php      

PCとSPでテーマは分かれていて、SPテーマのsingle.phpの中には通常ページ用の記述とAMP用の記述の両方が書いてあるので、AMPにかかわらずsingle.php自体は一つ。
style-amp.phpstyle.cssとほぼ同じ内容のCSSデータが吐き出されたphpファイルで、AMPページではこれをスタイルとして読み込みます。
partsフォルダの中にはページをまたいで使うパーツが入っていますが、これらの中身がAMP対応となるようにgulpからの吐き出しの際に置換したものがparts-ampに入っています。

つまり、AMPページとしては、

ということになります。

AMPのプラグインを使い倒そう

それではプラグインの関数を使って、AMPページを実際に作っていきましょう。

カスタムテーマを適用させる

AMPプラグインのreadme.mdの298行目から書いてありますが、プラグイン側に、カスタムテーマを利用したい場合に利用できるフィルターフックが用意されています。
WebNAUTでは、AMPページとしてsingle.phpstyle-amp.phpを読ませたいので、theme/sp内のfunctions.phpに下記のように記述しています。

add_filter('amp_post_template_file', 'amp_template', 10, 3);

function amp_template($file, $type, $post) {
    if ('single' === $type) {
        $file = get_template_directory() .'/single.php';
    }
    if ('style' === $type) {
        $file = get_template_directory() .'/style-amp.php';
    }
    // 同様の記述で他の読み込みファイルも指定できます。

    return $file;
}

これで、AMPページのリクエストを受けた際に、プラグインのデフォルトテーマを上書きする形で、single.phpstyle-amp.phpを適用することができるようになります。

なお、style-amp.phpを読み込ませるためには、テンプレートの<head>内に下記の記述をしておきましょう。
これで、<head>の中身が読み込まれるタイミングでstyle-amp.phpの中身がCSSとして差し込まれる形になります。


single.php内でAMP・非AMPを出し分ける

次に、single.php内での通常表示とAMP表示の出し分けに関しては、下記のようにフラグ変数を利用することで対応できます。


    AMPページの記述

    通常ページの記述

WebNAUTではこれを利用して、例えば下記のようにparts内のパーツを読むのか、parts-amp内のパーツを読むのかを条件分岐させています。

// おすすめ記事パーツの読み込み

記事本文を操作する

また、記事本文の吐き出しに関しては、通常<?php the_content(); ?>を使用していると思いますが、AMPのプラグインでこの代替となっているのが、

get('post_amp_content'); ?>

です。
この吐き出しが、記事本文の<img>タグを<amp-img>にしてくれたりと、至れり尽くせりの活躍をしてくれます。

先ほどのフラグ変数を使って、single.php内で

get('post_amp_content'); ?>

のように書いてあげれば、通常ページとAMPページでうまいこと出しわけができそうですね。

ただ、WebNAUTではシンタックスハイライトを有効にするプラグインを利用していて、この関数を使って本文の表示を行うと今度はシンタックスハイライトが機能しなくなってしまうという事態に陥ってしまいました。

そこで、あまり綺麗なやり方ではありませんが、通常通り<?php the_content(); ?>を使用しつつ、コンテンツ表示の際にフィルターフックをかけて<img><amp-img>に置換するなどのやり方で本文をAMP対応させています。

AMPチェックをしよう

上記のやり方で、一旦はAMP対応ページが出来上がるかと思います。

AMPページとして問題がないかどうかは、AMPページのURL末尾に#development=1を付けてコンソールから確認してみましょう。
AMP validation successful.」と出ればAMP対応完了です。
ちなみに、こちらのGoogleのAMPテストツールでもAMPのバリデーョンはチェックできます。

AMPの構造が正しいかどうかは、Googleの構造化データテストツールでも確認してみましょう。

WebNAUTのリニューアル作業では、バリデーションチェックではエラーは出ていなかったのですが、構造化ツールの方では下記二件のエラーが出てしまいました。

WebNAUTでは<head>部分に

を記述して、プラグイン経由でSchema.org(検索結果ページのカルーセルに表示するための情報)を出力させていましたが、二つのエラーはいずれもこの部分に関するものです。

一つ目のサイトロゴ問題に関しては、WordPress備え付けの設定でロゴを指定することで解決するのですが、その場合faviconと共通のものになってしまい、正方形にせざるを得なくなってしまいます。
AMPの推奨しているロゴは60x600の範囲のものとなっているので、せっかくなら横長のものにしたいところです。

そんな時は、下記のようにmeta情報操作用のフィルターフックで、meta情報のJSONを上書きしてしまいましょう。

add_filter('amp_post_template_metadata', 'amp_modify_json_metadata', 10, 2);

function amp_modify_json_metadata($metadata, $post) {
    $metadata['publisher']['logo'] = array(
        '@type' => 'ImageObject',
        'url' => '画像のurl',
        'height' => 高さ,
        'width' => 幅,
    );

    return $metadata;
}

これで任意のサイトロゴがSchema.orgのmeta情報として登録されます。

二つ目のエラーに関しては、カルーセル表示の際のサムネイルとなる画像のパスがルート相対で書かれていたことが原因でした。
PCテーマのfunctions.phpの方でアップロード画像のパスがルート相対となるような記述をしていたのですが、その画像がSPでもそのまま使われてしまっていたからですね。

そこで、先ほどのamp_modify_json_metadata関数内のreturnの前に、下記のように追記すれば、うまいことフルパスで上書きできそうです。

// 記事のサムネイルURLをフルパスで取得
$post_thumbnail_id = get_post_thumbnail_id($post->ID);
$image = wp_get_attachment_image_src($post_thumbnail_id, 'full');
$image_url = $image[0];

// メタ画像URLを上書き
$metadata['image']['url'] = $image_url;

これでエラーは出なくなりました。

カルーセルに掲載される日を首を長くして待ちましょう。

まとめ

WordPressのAMP対応は今回紹介した方法以外でも実現できますし、後からAMPページを追加するのか、新規立ち上げで最初からAMPありきの開発をするのかでもベストプラクティスは変わってくるので、状況に応じて参考にしていただければと思います。

また、他にもGoogle Analyticsの導入やAMP対応ハンバーガーメニューの実装など、細かい対応は必要になってきますが、それはまた別の機会の紹介としたいと思います。

疑問点や不明点、修正点などあれば@WebNAUT_BWまでお願いします!