BloggerでAMPに対応
かなり強引ですが、BloggerのページをAMPに対応させてみました。使っているBloggerの機能によっては動かなくなることもあるかもしれませんが、筆者の環境では動かすことができました。
AMPページの区別
本来はAMPページも非AMPページを持ちcanonicalとしてそのアドレスを指定するのが正規の方法のようですが、AMP対応ページはAMPのみとしました。
なので、表示するページによってAMP用の出力とそうでないものを区別する必要があります。 筆者はページタイトルに存在する文字によってそれを区別することにしました。
設定した文字は「⚡」AMPの雷マークです。この文字がタイトル中に存在する記事はAMP用の出力をして、そうでないものは従来通りの出力とします。
テンプレートxmlの修正
テンプレートxmlのhead部の記述を公式:AMP HTML ページを作成するに従って修正していきます。
公式ページに書かれている手順は次の通りです。
- 先頭に <!doctype html> doctype を指定する
- 最上位階層のタグを <html ⚡> にする(<html amp> も可 )
- <head> タグと <body> タグを含める
- <meta charset="utf-8">タグを<head>タグの最初の子要素にする
- <script async src="https://cdn.ampproject.org/v0.js"></script> タグを <head> タグの 2 番目の子要素にする
- <head> タグ内に <link rel="canonical" href="$SOME_URL"> タグを含める
- <head> タグ内に <meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1"> タグを含める
- <head> タグ内に AMP ボイラープレート コードを含める
1,3,6に関してはBloggerの標準機能で対応しています。
2の対応方法ですが、b:attrを使って親要素に属性を追加します。Bloggerのxmlでは値を持たない属性を持つことができないので、amp="amp"としました。
(htmlタグの後) <b:attr cond='data:blog.pageTitle contains "⚡"' name='amp' value='amp'>
4,5に関してですが、通常bloggerのheadの最初の子要素は、自動で出力されるCSSを読み込むタグです。なのでこれを除去しなければ最初のタグと2番目のタグを実現できません。次のように書き込むことで除去ができます。もしBloggerデフォルトCSSの読み込みが必要なら、この後で手書きします。
<!--<head>--> <head>
また、次のように記述してAMPでないページの時は4,5,8の設定を出力しないようにします。
AMP ボイラープレート コードとはリンク先のコードのことです。そのままコピーして貼り付けてください。
<b:if cond='data:blog.pageTitle contains "⚡"'> <meta charset='utf-8'/> <script async='async' src='https://cdn.ampproject.org/v0.js'/> <!-- ボイラーテンプレート --> <style amp-boilerplate='amp-boilerplate'>body{-webkit-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-moz-animation:-amp-start 8s steps(1,end) 0s 1 normal both;-ms-animation:-amp-start 8s steps(1,end) 0s 1 normal both;animation:-amp-start 8s steps(1,end) 0s 1 normal both}@-webkit-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-moz-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-ms-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@-o-keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}@keyframes -amp-start{from{visibility:hidden}to{visibility:visible}}</style><noscript><style amp-boilerplate='amp-boilerplate'>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript> </b:if>
ここでも本来値を持たない属性であるasyncやamp-boilerplateには名称と同じ文字列を持たせています。
テスト
この状態でgoogleのAMPテストでAMPページになっているか確認していきます。
- htmlタグ内のxml系の属性の問題
こちらによるとAMPではxml系の属性値は許可されていません。そこで次のようにして除去します。
(htmlタグの後) <b:if cond='data:blog.pageTitle contains "⚡"'> <!-- amp属性の付与 --> <b:attr name='amp' value='amp'/> <!-- 不要属性の削除 --> <b:attr name='xmlns:b' value=''/> <b:attr name='xmlns:data' value=''/> <b:attr name='xmlns:expr' value=''/> <b:attr name='xmlns' value=''/> </b:if>
html amp="amp"の記述にまとめました。
- divのname属性は認められない問題
bloggerではb:sectionがdivタグに変わります。その際name属性もそのまま出力されるので、b:sectionに設定するname属性を除去します。
- form(検索バー)の問題
Bloggerの検索バーをページで表示しているとエラーとなります。その際は、エラー時のメッセージに示されているようにheadに<script async custom-element="amp-form" src="https://cdn.ampproject.org/v0/amp-form-0.1.js"/>を加えます。
- オリジナルのJavaScriptが使えない問題
カルーセルやアコーディオンなどAMPのライブラリにいくつか機能があるので、サイトの共通機能となっているJavaScriptがあれば、AMPの機能に置き換えます。非AMPページでもこれらの機能は使えます。またどうしても実現できない場合は、先の⚡マークでの分岐を使ってJavaSciptコードの出力を非AMPページだけにしたり、非AMPページの本文内にスクリプトを移動したりして、AMP化のページではそれらの機能をあきらめるという方法もあります。
また、CSSをコメント化したのと同様の方法で、headが閉じられる前のlinkタグと、bodyが閉じられる前に出力されるBlogger用のJavaScriptもコメントアウトします。
<!--</body>--> </body>
- imgタグの問題
テンプレート中だけでなく本文にあるものを含めてimgタグをすべて修正する必要があります。imgタグをamp-imgタグに置き換えます。この時widthとheightが必須属性となります。layout属性に"responsive"を設定すると画像サイズが可変、fixedにすると固定となります。
JavaScriptが動かないときにamp-imgは認識されません。amp-imgの内側で、noscriptタグで囲んで既存のimgタグも併記します。Bloggerはイメージのサムネイル化の際にimgタグの画像しか扱いませんので、書いておかないと「人気の記事」や「注目の記事」ガジェットに影響します。
- styleタグのamp-custom属性の問題
AMP時にはsylteタグ内にamp-custom属性を付与しないといけません。sytleタグは内部でb:skinから作成されます。しかしb:skinに何かしようとしてもうまくいきませんでした。試行錯誤の結果、b:skinは記述必須項目ですが、出力しなくてもいい事が判明しました。
b:ifによる条件分岐を使ってb:skinを読み飛ばします。b:skinはBloggerのUIからサイズや色などを指定する際に用いられるもので、もともと筆者はこの機能を使っていませんので常に成立しないような条件にして、必要なスタイルシートはすべてベタ書きにしています。
非AMPページだけその設定を生かしたいのなら、条件をタイトルに⚡マークがあるかどうかにしてください。
またAMP時はスタイルシートにamp-custom属性が必要です。
<style> <b:attr cond='data:blog.pageTitle contains "⚡"' name='amp-custom' value='amp-custom'/> /* CSSを全て手入力 */ </style> <b:if cond='1==2'> <b:skin><![CDATA[中身は削除します]]></b:skin> </b:if>
analyticsやAdSense
google analyticsやAdSense広告を付けている場合は、これらにもAMP専用の記述が必要です。headの中とbodyの最初で次のコードを記述するだけですが、大事なことなので念の為AMP ページにアナリティクスを追加するや、Accelerated Mobile Pages(AMP)についてを確認してください。
head部
<b:if cond='data:blog.pageTitle contains "⚡"'> <script async='async' custom-element='amp-auto-ads' src='https://cdn.ampproject.org/v0/amp-auto-ads-0.1.js'/> &;lt;script async='async' custom-element='amp-analytics' src='https://cdn.ampproject.org/v0/amp-analytics-0.1.js'/> <b:else> <!-- 通常時のAdSense用スクリプト読み込み --> <!-- 通常時のanalytics用のスクリプト読み込み --> </b:if>
body直後
<b:if cond='data:blog.pageTitle contains "⚡"'> <amp-auto-ads type='adsense' data-ad-client='ca-pub-xxxxxxxxxxxxxx'/> <script type="application/json"> {"vars" : {"gtag_id": "トラッキングID","config" : {"トラッキングID": { "groups": "default" }}}} </script> </b:if>
このような修正を経て、AMP対応が実現しました。