※この記事は2017年1月16日に執筆された記事です。現在は仕様が異なる可能性があります。
技術の移り変わりの早さに翻弄されているエンジニアの皆さんこんにちは!
先日のWebNAUTリニューアルの目玉のひとつとして「AMP対応」というものがありましたが、今回はそれを例に、「WordPressのオリジナルテーマを、プラグインをうまいこと使ってAMP対応させてみよう」というテーマで記事を書いてみました。
AMPとは?
AMP(Accelerated Mobile Page)とは、GoogleなどのCDNにページの情報がキャッシュとして保持され、検索からのページ訪問の際にびっくりするほど表示が早くなるという夢のような技術です。
下の画像のように、検索結果ページのディスクリプション領域に、「⚡️AMP」の表記があるのがAMPページです。最近よく見るようになりましたね。
AMP対応させるには、通常のhtmlタグの記述とは異なる「AMPタグ」なるものを適宜使用しなくてはならないことに加え、例えば下記のような制約があります。
- 一部のhtmlタグが使用不可
- 原則としてJavaScriptは使用不可
- CSSはヘッダーに直接埋め込み、かつサイズは50KB以下
- head部分に構造化データの記述をする必要がある
上記含めた諸々のAMPルールをクリアすると、Googleのクロールの際にAMPページとしてインデックスされ、晴れて検索結果に稲妻マーク⚡️付きのページが表示されるわけですね。
全体のルールはAMP Projectのサイトに載っているので、そちらを見てみてください。
WordPressのAMP化は?
いまご覧いただいているWebNAUTはCMSとしてWordPressを使用しているのですが、WordPressのAMP対応にはプラグインが便利です。
Automatic社製の公式プラグインなので安心ですね。
ただ、このプラグインを有効化させただけだと、こんな風にこれ以上ないデフォルト感漂うサイトとなってしまいます。
これは、wp-content/plugins/amp/theme
内のテーマが適用されてしまうためです。
さすがにこれで「AMP対応しました!」とは言えないので、AMPページであっても通常のスマホページと同じ見え方となるように手を加えていきましょう。
やり方としては、
- AMP用の
single.php
を別途作成する - 通常ページに適用しているテーマの
single.php
内で、AMP表示と通常表示の出しわけを行う
の2パターンが考えられましたが、今回は通常ページとAMPページでデザインは統一するということもあり、保守性を考慮して後者を選択しました。
WebNAUTのwp-content/theme
内の構造としては、このような感じになっています。(分かりやすいように一部を省略、並び順も変更しています)
theme ├pc │ ├... │ └sp ├functions.php ├header.php ├footer.php ├index.php ├single.php <- 通常表示とAMP表示が両方記述されている ├parts <- 各種パーツフォルダ │ ├hoge.php │ ├piyo.php │ ├... │ ├parts-amp <- AMP用の各種パーツフォルダ │ ├hoge-amp.php │ ├piyo-amp.php │ ├... │ ├style.css <- 通常ページのCSS ├style-amp.php <- AMPページのCSS ├...
PCとSPでテーマは分かれていて、SPテーマのsingle.php
の中には通常ページ用の記述とAMP用の記述の両方が書いてあるので、AMPにかかわらずsingle.php
自体は一つ。
style-amp.php
はstyle.css
とほぼ同じ内容のCSSデータが吐き出されたphpファイルで、AMPページではこれをスタイルとして読み込みます。
parts
フォルダの中にはページをまたいで使うパーツが入っていますが、これらの中身がAMP対応となるようにgulpからの吐き出しの際に置換したものがparts-amp
に入っています。
つまり、AMPページとしては、
- 通常通り
single.php
を読み、 - スタイルに関しては
style-amp.php
を読み、 - 各種パーツに関しては
parts-amp
フォルダ内ファイルを読み込めば良い
ということになります。
AMPのプラグインを使い倒そう
それではプラグインの関数を使って、AMPページを実際に作っていきましょう。
カスタムテーマを適用させる
AMPプラグインのreadme.md
の298行目から書いてありますが、プラグイン側に、カスタムテーマを利用したい場合に利用できるフィルターフックが用意されています。
WebNAUTでは、AMPページとしてsingle.php
とstyle-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.php
とstyle-amp.php
を適用することができるようになります。
なお、style-amp.php
を読み込ませるためには、テンプレートの<head>
内に下記の記述をしておきましょう。
これで、<head>
の中身が読み込まれるタイミングでstyle-amp.php
の中身がCSSとして差し込まれる形になります。
<style amp-custom> <?php $this->load_parts(array('style')); ?> <?php do_action('amp_post_template_css', $this); ?> </style>
single.php内でAMP・非AMPを出し分ける
次に、single.php
内での通常表示とAMP表示の出し分けに関しては、下記のようにフラグ変数を利用することで対応できます。
<?php $is_amp = false; if(function_exists('is_amp_endpoint') && is_amp_endpoint()) { $is_amp = true; // ampだとtrue, 非ampだとfalse } ?> <?php if($is_amp): ?> AMPページの記述 <?php else: ?> 通常ページの記述 <?php endif; ?>
WebNAUTではこれを利用して、例えば下記のようにparts
内のパーツを読むのか、parts-amp
内のパーツを読むのかを条件分岐させています。
// おすすめ記事パーツの読み込み <?php if($is_amp): ?> <?php get_template_part('/parts-amp/amp-recommend'); ?> <?php else: ?> <?php get_template_part('/parts/recommend'); ?> <?php endif; ?>
記事本文を操作する
また、記事本文の吐き出しに関しては、通常<?php the_content(); ?>
を使用していると思いますが、AMPのプラグインでこの代替となっているのが、
<?php echo $this->get('post_amp_content'); ?>
です。
この吐き出しが、記事本文の<img>
タグを<amp-img>
にしてくれたりと、至れり尽くせりの活躍をしてくれます。
先ほどのフラグ変数を使って、single.php
内で
<?php if($is_amp): ?> <?php echo $this->get('post_amp_content'); ?> <?php else: ?> <?php the_content(); ?> <?php endif; ?>
のように書いてあげれば、通常ページと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のリニューアル作業では、バリデーションチェックではエラーは出ていなかったのですが、構造化ツールの方では下記二件のエラーが出てしまいました。
- 「logo」フィールドの値は必須です。
- 「image.url」には有効な URL を指定する必要があります。
WebNAUTでは<head>
部分に
<?php do_action('amp_post_template_head', $this); ?>
を記述して、プラグイン経由でSchema.org(検索結果ページのカルーセルに表示するための情報)を出力させていましたが、二つのエラーはいずれもこの部分に関するものです。
一つ目のサイトロゴ問題に関しては、WordPress備え付けの設定でロゴを指定することで解決するのですが、その場合faviconと共通のものになってしまい、正方形にせざるを得なくなってしまいます。
AMPの推奨しているロゴは60×600の範囲のものとなっているので、せっかくなら横長のものにしたいところです。
そんな時は、下記のように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までお願いします!