TOP » WEB » Wordpress » 自作WordPressテンプレートをプラグインを使わずにAMP化してみた話
自作WordPressテンプレートをプラグインを使わずにAMP化してみた話

自作WordPressテンプレートをプラグインを使わずにAMP化してみた話

独自WordpressテンプレートのAMP化

現在このサイトは自分で構築したオリジナルのWPテンプレートを使っているけど、AMP化は対応していなかった。
プラグインを使えば簡単に実装はできるかもしれないけど、見た目の自由がきかなさそうで嫌だなという点と、何より実装が非常に面倒くさそうということからずっと見送っていた。

ただGoogle先生お墨付きだし、今はそこまでSEO的な恩恵を感じにくいけど早い段階で実装しておくことで後々効いてくるんじゃないかなぁとか思ったので、今回プラグインを使わずに独自でAMP化処理を行なってみたお話です。

記事詳細テンプレートの切り替え

今回記事詳細ページだけをAMP化することにしたので、まず記事詳細ページにアクセスした時にAMP専用テンプレートに切り替わるようにします。

AMPページのURL

テンプレートの切り分け方法は色々あると思いますが、今回は記事詳細URLに「amp=1」というパラメーターがある場合のみAMP化したテンプレートに切り替わるようにしました。
例えばこの記事なら以下のURLでAMPページになります。

https://nonbiri.life/web/wordpress/amp/?amp=1

linkタグにAMP用URLを記載する

次にAMP対応するにあたって、非AMPページにはAMPページのURLをhead内に明記して、逆にAMPページは非AMPページのURLを明記させて同じページであることを示します。
使用テーマのhead内に直接書いてもいいですが今回はfunctions.phpに下記のように記述しました。

これで記事詳細ページ出力時に「<link rel=”amphtml” href=”【現在のURL】?amp=1″>」というlinkタグが出力されるようになりました。

次はURLパラメーターに「amp=1」があれば記事詳細テンプレートをAMP専用テンプレートに切り替える処理になります。
同じくfunctions.phpに下記の記述を加えます。

「single_template」フィルターフックを使って記事詳細テンプレートが読み込まれる際に処理を割り込ませます。
実行する関数「change_amp_template」の第一引数には本来使用されるテンプレートファイル名が渡されるので、「$change_template」に格納し直しときます。
書いてる時に思ったんですけど別に格納し直さないでそのまま「$single_template」でもいいですねこれ。

次にURLパラメーターに「amp」が存在しているかと、存在してる場合値が「1」かどうかを確認して、条件に合致する場合は「locate_template」で使用するAMPテンプレートファイル名を「$amp_template」に格納します。
今回はAMPテンプレート名を「amp.php」としていますが、ここは任意の名前で大丈夫です。

emptyでちゃんとファイル名が入っているか(ファイルが存在していたか)を確認して、問題無ければ「$change_template」の中身を先ほどのAMPテンプレート名に差し替えます。
そして最後にreturnでテンプレート名を返して完了です。

これで記事詳細URLの末尾に「?amp=1」を付けてアクセスするとAMPテンプレートが適用されるわけです。
ただ、まだテンプレートの「amp.php」を作成していないので、実際にURLを叩いても切り替わることはありません。
次にAMP専用テンプレートを作成していきます。

AMPテンプレート(amp.php)の作成

AMPの基本テンプレートはAMPプロジェクトのHPにも公開されていますが下記のhtmlが基本となります。

Accelerated Mobile Pages Project – AMP

上記基本テンプレートに独自のCSSを書きこんだり、iframeやlightbox、google analytics等を使用するのに必要な拡張コンポーネントを書き加えていきます。

通常のWPテンプレートであればヘッダーやフッター等の共通部分は「get_header」や「get_footer」で共通パーツを読み込んで処理するのですが、AMPでそれをすると、そこから除外しなければいけないタグの数が多く制御が大変なので自分は共通パーツは読み込まないようにして、独自のヘッダーやフッターの内容を直接AMPテンプレート内に記述するようにしています。

ヘッダーまでの完成形

ヘッダーまでの完成形は下記になります。

上から順に解説していきましょう。

canonical

まず「canonical」ですが、冒頭で説明した通り、非AMPページのURLの記載が必要なので、「get_permalink」で現在の記事URL(?amp=1部分を除く)を出力します。

カスタムフォント

次にGoogle Fontsからフォントを読み込んでいます。当然これはこのサイトで使用しているだけなので不要な人はここの記述はいりません。
AMPページは通常外部cssは読み込み禁止ですが、一部のサイトからのフォント配信は許可されています。
2018年9月現在で許可されているサイトは下記になります。

  • Typography.com
  • Fonts.com
  • Google Fonts
  • Typekit
  • Font Awesome

title

「title」は非AMPページに合わせて「【記事タイトル】 – 【サイト名】」にしていますが、ここは任意の形で。

スタイルシート

カスタムフォントの項で述べた通り、AMPでは原則CSSファイルからの読み込みを禁止しています。なので独自のCSSに関しては直接インラインでcssを書く必要があり、<style amp-custom>タグの中に記述します。

自分はインラインcss部分を別のPHPファイル(amp-style.php)で管理して、それを「get_template_part」で出力するようにしています。
ただ、非AMPページのCSSとAMPページのCSSが別々になるので何か共通デザイン部分で修正が発生した場合、両方を修正しなければならないのでちょっとネックです。
何かひとつにまとめられるような方法があれば良いんですけど。

構造化データ

schem.orgで記事に関する著者や記事のサムネイル画像、公開日など詳細な情報を記載し、それをGoogleなどの検索エンジンに正確に収集してもらいます。
これは自分もなかなか理解できていないところもあったので、色々な記事を参考にしつつ今の形に落ち着きました。
一応Googleの「構造化データテストツール」でもエラーは出ていないので大丈夫なはずです。

デフォルトスタイル

「style amp-boilerplate」部分はAMPページに必要なデフォルトのCSSになるので触らずそのままにします。

拡張コンポーネント

最後に拡張コンポーネントを記述していきます。今回使った拡張コンポーネントは

  • google analytics
  • フォーム
  • 広告
  • iframe
  • 画像のlightbox処理
  • ソーシャルボタン
  • Gists(ソースコード)の埋め込み

の7つになります。逆に言えばこれらの処理は拡張コンポーネントが無ければ使えないということです。

なおgoogle analyticsに関してはログイン状態とローカル環境では使用しないようにして、GistsはGistsの貼りつけがないページで使用するとエラーとなってしまうようなので関数(load_amp_gist)にて条件分岐して出力するようにしています。

head以降の記述

これでhead内に関しては完了です。残りのbody以降に関しては非AMPページのデザインに寄せるのか全然違ったデザインにするのかで変わってくるのですが、非AMPページのテンプレートからコピペしてくる、もしくは同一テンプレートを読み込んで処理する場合はタグによってはそのまま使うことができないのでAMPページ用に調整が必要です。

例えば「img」タグはAMPページでは使えないので全て「amp-img」に変換して、widthとheight属性を省略していた場合は必須になるので必ず記述するようにします。

<img src=”/img/image.jpg” alt=”画像”>
であれば
<amp-img src=”/img/image.jpg” width=”300″ height=”200″ alt=”画像”></amp-img>
となり、imgと違いamp-imgには閉じタグが必要になります。
といいつつ、閉じタグをつけていない箇所が自分のテンプレート内にあったのをこれを書いてる時点で発見したけど、特にGoogleのAMPテストではエラーにはなっていないようでした。
だからといって閉じないままにしてても、いつエラー判定をくらうようになるか分からないのでちゃんと</amp-img>で閉じるようにしましょう。

他にもiframeやフォームなどそのままでは使えない箇所があればAMP用のタグに差し替える必要があります。
どれがそのまま使えてどれが使えないかは上げだしたらきりがないので、AMPテストなどでチェックしてエラーとなってる箇所を一つ一つ潰していった方がいいかもしれないです。
現在使用できるコンポーネントは以下のサイトで確認できます。

コンポーネント/タグ – AMP

見ての通り、割とほとんどのことは代替のコンポーネントが用意されているのではないでしょうか。

記事本文の対応

テンプレートの方はここまででAMP化できたと思います。
残るは記事本文内の使用できないタグをAMP用に差し替える作業になります。

冒頭のAMP用のテンプレートに切り替える処理に本文内のタグをAMP用に切り替える処理を加えていきます。
完成形は以下の通りです。

「$change_template」にAMP用テンプレートのファイル名を差し替えた後に処理を挿入していきます。

まずフィルターフックで本文を出力する「the_content」に対して、本文の内容を差し替える「the_content_filter」を実行します。
「the_content_filter」の引数「$content」には本文の内容が引き渡されるので、それに対して「preg_replace」で差し替えや削除を行なっていきます。
こういう置換処理を行なう際、正規表現は避けて通れないのですが、自分はどうにも苦手で毎回苦戦するんですよね…

border属性の削除

imgやtableなどに付与されている可能性のある「border」属性はAMPでは使えないので削除します。

lightbox処理

自分が使用しているオリジナルテーマでは貼りつけた画像に対して、メディアファイルへのリンクが貼られている場合、「a」タグに対して「data-lightbox=”lightbox”」を付与し、拡大画像をlightboxで処理するようにしています。
くどいようですがAMPでは独自のjsなどは一切使用できないので、lightboxの処理もAMPが用意しているものに差し替える必要があります。

AMPのlightboxを使うには<amp-image-lightbox>の記述が必要になります。また属性として「layout=”nodisplay”」の指定が必須です。あと必須ではないですが「id」属性に任意のid名も割り振っておきましょう。

そして拡大したい画像に対して「on=”tap:【ID指定】”」「role=”button”」「tabindex」の指定をします。
「tap:【ID指定】」のID部分は先ほどamp-image-lightboxに指定したid属性の値を指定します。

こんな感じです。
imgはAMPでは使用できないタグですが、これは後で一括で処理します。

書いてて気づいたんですが、自分のやり方だと全てのlightbox処理を行う画像に対してamp-image-lightboxが生成されてしまうんですが、これ別に1つあればいいかもしれません。
まあエラーはでていないので良しとしていますが。

Amazonアソシエイト

自分のサイトではAmazonアソシエイトのリンクを「Amazon associates link builder」プラグインを使って吐き出していますが、吐き出される画像に対してAMPでは必須となる「width」と「height」が記述されていません。
なのでまず該当画像のURLのみを取得して、そのURLに対して「getimagesize」関数でwidthとheightを取得して、付与するという処理を行なっています。
また、このプラグインでは計測用と思われる透明な画像が埋め込まれているのですが、そのせいで謎の空間が空くようになっていたので、cssで非表示にするため特定のクラスを付与するようにしています。

これも書いてる時に気づいたんですが、商品によっては上手くwidthとheightを取得できていないものがあり、AMPエラーが出ているページがありました。
現在調査中。

imgタグの差し替え

前述でも書きましたが、AMPではimgではなく「amp-img」とする必要があるので、一括で変換しています。
またその際、「layout=”responsive”」とし、画面幅に合わせて拡大・縮小するように指定しています。

style、target、onclick属性の削除

styleやtarget、onclickなどの使用できない属性を削除します。
ただaタグのtargetに関しては「_blank」のみ許されるそうですが、自分の処理では全部削除してます。
後々余裕があればこの部分の処理は変えておきたいですね。

gist

ソースコードを埋め込むの使用しているgistを専用の<amp-gist>タグに差し替えています。
amp-gistには「data-gistid」属性にgistのIDを指定する必要があり、IDは埋め込み用jsファイルのファイル名になります。

例えば
<script src=”https://gist.github.com/XXXXXX/701acf0c9ed56b9c6ee86ff12ec01096.js”></script>
であれば、「701acf0c9ed56b9c6ee86ff12ec01096」がIDになります。

fontタグの削除

fontタグは使えないので削除です。

youtube

youtubeの埋め込みタグとなるiframeを専用の<amp-youtube>タグに差し替えています。
amp-youtubeには「data-videoid」属性に動画のIDを指定する必要があります。

iframe

通常のiframeはwidthとheight、srcの値をバラバラに格納して、<amp-iframe>タグに組み立て直しています。

ブログカード

ブログカードの「security」や「marginwidth」などの不要な属性を削除しています。

チェック

最後にGoogleのAMPテストやchromeのデベロッパーツールなどでエラーを確認して、エラーが無ければ完了です。
記事によっては上記の処理では足りないことが出てくると思うので、その都度置換処理を追加していきましょう。

しかしもっとうまいやり方ないですかね…ガワのテンプレートは自分で用意するから吐き出す本文内のみ勝手にAMP処理してくれるプラグインとかないかな。