AMP対応用の個人的メモです。
「個人的メモ」と書けばどんな状態でもは許されるとは思っていませんが、整理するのも面倒な量になったためあまり整えず記述しています。
今後、訂正や更新も兼ねて徐々に直していければと思います。この件に関してモチベーションが続けばですが。
なお、当記事の方法が正解ということではまったくありません。
試した過程の記録のようなものに過ぎず、動作保証やいつまで使えるのかもわかりません。
記事内で参考に挙げている別の方の記事のほうが正解に近いと思いますので、AMPに関してまともな情報が欲しい方は、本記事末尾の参考リンクのみご利用ください。
なお、AMPのバリデーターは以下のリンクから。
実現したいこと
実現したいことは以下の通り。
- WordPressのAMP対応
- プラグインを使わない
- 対応範囲を絞って簡素な形に
AMPは要素が増加していますが、増加の度に手を入れるのは手間がかかり過ぎるので、現時点でも最低限のあたりを目指したいと思います。
AMPをどう実現するか
以下の形での実現を目指しました。
- AMPページはURLの末尾に「?amp=1」をつける
- パラメーターの有無で分岐
- ampに対応させるのは 投稿ページと固定ページ(と添付ファイルページ)
- 本文中のscriptタグは消す
- サイドバーとコメントは消す
後述しますが、本記事ではis_singular()を用いるので、投稿ページと固定ページだけではなく添付ファイルのページも含んでいます。
添付ファイルのページは特に必要ではなかったのですが、テンプレート階層的にsingle.phpで対応可能であり、添付ファイルのページのためだけに必要な処理もなさそうなので、この形にしてみました。
scriptタグに関しては、これが記事内に存在するかどうかを条件に加えている参考記事もありますが、本記事では思い切ってscriptタグを消すという方法をとっています。
この辺りはそれぞれのサイトごとに判断しなければならない部分ですから、各自判断ということで。
分岐方法の検討
分岐の方法自体は悩みましたがなるべく簡易に、といいますかAMPをすぐやめられるようにと考えると、AMP用のテンプレートを作成してまとめてしまうことが最善かなと考えています。
ところが、プラグイン作成の技術が必要なようで、今の私ではうまくいきそうになく。
結局部分ごとの対応という形に落ち着き、そこから更に試行錯誤で以下の形にしました。
- functions.php内にAMP用の仕組みを作る
- 主にheader.phpのhead内でAMP用と非AMP用の記述を分岐して読み込ませる
- single.phpとpage.phpはそれぞれ内部で分岐
header.php内に分岐内容まで書くと長くなるので、headに読み込む記述をそれぞれ以下のようなファイルに分けて管理しています。
- AMP用のamp-head.php
- 非AMP用のno-amp-haed.php
他の方法もあったのですが、個別に手を加える部分が増える反面、柔軟性が高いかなと考えて決めました。
AMP関連ファイルを一つにまとめる
AMP関連ファイルを一つにまとめるには、以下の記事の「TEMPLATEPATHの変更」の部分を参考にすれば実現できると思います。
仕組みとして、functions.phpの適用範囲を超えるためプラグイン化が必要ですが。
AMPのチェック
AMPへの分岐の基点となる重要なポイントが、AMPの分岐作成です。
私の場合は、functions.phpに以下のように関数で記述しています。
function check_amp(){
if(isset($_GET['amp'])){
if($_GET['amp'] === '1' && is_singular()){
return true;
}
}
}
この形でなくともよいのかもしれませんが、functions.php内でもAMP用の分岐が使えますので、便利かなと思っています。
functions.php内での分岐
functions.php内での分岐方法の例は以下の通りです。
add_action( 'template_redirect', 'set_amp_setting' );
function set_amp_setting(){
if(check_amp()){
//処理を書く
}
}
基本的に分岐用関数はフックの中に書くため、適切なフックを用いないと動作しません。
本記事では上記のtemplate_redirectへのフックで大半の動作が可能でしたが、フックへの理解が甘い点を痛感しています。
なお、functions.php内にはAMPで動いてほしくないものもあると思いますので、その際はif(!check_amp())と記述して分岐をつくり、除外するようにしています。
テンプレート内での分岐方法 1
前項の関数を記述した上で、single.phpなどに以下のようにすれば、そのテンプレート内でAMP用の分岐が使えます。
<?php
$myAmp = false;
if(check_amp()){
$myAmp = true;
}
?>
<?php if(!$myAmp): ?>
<!--処理を書く-->
<?php else: ?>
<!--処理を書く-->
<?php endif; ?>
テンプレート内でAMPかどうかの判定を使い回す前提で、変数内に真偽値を入れる形にしています。
テンプレート内での分岐方法 2
例えば、header.phpに以下のように記載し、真偽値の入る変数をグローバル変数にします。
<?php
global $myAmp;
$myAmp = false;
if(check_amp()){
$myAmp = true;
}
?>
次いで、footer.phpには以下のように記載します。
<?php global $myAmp; ?>
こうすれば、header.phpだけではなくfooter.phpにも真偽値が渡るので、チェック用の関数をテンプレートごとに実行しなくとも分岐は可能です。
これが良いかどうかはまた別の話ですが、一応テンプレート間で変数の値を渡す際のメモとして記載します。
functions.php
細かく書くとかなり大変なのと、メモなのでとりあえず書き出す形にします。
AMP分岐用関数と専用ページテンプレートの分岐
まず、既に前述していますがAMP用の設定です。
//AMPチェックの関数化
if (!function_exists('check_amp')) {
function check_amp(){
if(isset($_GET['amp'])){
if($_GET['amp'] === '1' && is_singular()){
return true;
}
}
}
}
functions.phpのその他の部分
その他の部分は以下の通りです。
なお、コメントアウトしている部分は試作の段階で試したものを残しているだけであり、特に必要というわけではありません。
ショートコード
the_contentにフックして置換していますが、このままではショートコードが展開されずそのまま出力されます。
そこで、get_the_content()でショートコードを使えるようにするのと同様の処理を施しています。
//ショートコードを展開できるようにする
$content = do_shortcode( $content );
これでショートコードも展開されますが、展開してほしくないものもや、むしろ削除したいものもあるかもしれません。
その場合は、do_shortcode()は使わずに、以下のように個別の置換していく方法も考えられます。
//[delete_shortcode]というショートコードを削除する
$content = preg_replace('/\[delete_shortcodel\]/i', '', $content);
//[use_shortcodel]を本来の値に置換
$replacement_imgurl = esc_url(get_stylesheet_directory_uri());
$content = preg_replace('/\[use_shortcodel\]/i', $replacement_imgurl, $content);
本来の値に置換する例は、画像を表示する際にテーマフォルダまでのパスを出力するためのショートコードです。
この程度なら、ショートコードの設定時の記述をそのまま流用して変数にいれてしまえばよいので、比較的簡単に置換可能です。
本文中の要素
$content = preg_replace('/target[^>]*/', '', $content);
上記までの記述は、本文中にある不要な部分を置換して消す処理です。
the_contentにフックしている部分は、 AMP用プラグインのAMP – Accelerated Mobile Pages の中の記述を主に参考にしています。
そのため実際には全く記事中に存在しないものもあったりしますので、使う場合には適宜増やしたり減らしたりする方が効率的ではあります。
しかし、AMPがキャッシュ前提の技術であるとする場合、要素置換後のページがキャッシュされる都合上、置換による表示遅延はあまり関係がないはずです。
そうであるなら、限度はあるでしょうが遅延は気にせず置換を行うのもよいのではないかと思います。
canonicalの停止
WordPressで機能でcanonicalを表示した場合、パラメーターが付与されたままになるためエラーがでます。
そのため、AMPの分岐内で以下を記述して止めています。
remove_action('wp_head', 'rel_canonical');
その上で head に( head に関するコードは後述します)以下を記載して、パラメータ無しの URL を設定しています。
<link rel="canonical" href="<?php $pageid = get_the_ID(); echo get_permalink($pageid); ?>'">
rel_canonicalを用いてパラメーター付きの元々の値をremoveして設定し直すことも考えましたが、そこまでする必要もなさそうなのでこの方法にしています。
なお、以下は念のための参考用のリンクです。
Youtube と Tiwtter 埋め込み
上記2つは以下の内容を参考にさせて頂きました。
- WordPressで「特定のURLが含まれたiframe動画」のみをレスポンシブ表示する方法
- 【WordPress】プラグイン無しでAMP(Accelerated Mobile Pages)に対応にする手順
- amp-youtube
- amp-twitter
ちなみに、widthやheightの値に特別な理由は無く、単に公式のヘルプの参考例に従っている状態です。
なお、Twitterに関しては、例えば上記のコードではタイムラインの埋め込み(Twitter検索の埋め込みなど)に問題があるようです。
こちらはまだ原因究明や対応策の検討はできていません。
amp-imgに必要なwidthとheight
amp-imgにはwidthとheightの指定が必要です。
しかしWordPressの場合は、管理画面からメディアアップローダーを通して配置している画像に関してはサイズがほぼ自動で入っていると思いますので、今回は特に対策を講じていません。
なお、Search ConsoleのSearch Consoleのエラーでは、widthなどが設定されていない場合以下のような警告がでるようです。
AMP タグに無効なレイアウト プロパティがある
暗黙的レイアウト「CONTAINER」はタグ「amp-img」ではサポートされません。
広告
上記は広告部分ですが、記事内のh2要素の真上と記事下に自動で入れ込む(入れ込むのは同じ広告です)形をためしています。
ただ、amp-adのwidthとheightにどれほど意味があるのか分からず、元の広告のサイズを設定している状態です。
SNSボタン
//記事下にAMP用SNSボタンを配置
add_filter('the_content','add_snsbtn_above', 20);
function add_snsbtn_above($content){
//記事下にsnsボタン配置
ob_start();
get_template_part('amp-sns-bt');
$output_string = ob_get_contents();
ob_end_clean();
return $content.$output_string;
}
上記の部分では、amp-sns-bt.phpという適当な名称でファイルをつくり、以下の用に記述しています。
<div class="amp-snsbtn">
<amp-social-share type="twitter"
width="60"
height="44"> </amp-social-share>
<amp-social-share type="email"
width="60"
height="44"></amp-social-share>
</div>
これは下記のサンプルをそのまま使っています。
なお、Facebookに関してはサンプル通りにはいかないそうです。
上記記事内にある以下のコードでいけるようです。
<amp-social-share type="facebook" width="44" height="44"
data-param-app_id="FacebookのApp ID"
data-param-text="投稿したい文章"
data-param-href="投稿するリンク"
>
</amp-social-share>
内部リンクの向け先
上記部分は、自ドメインを「http://example.com」とした場合の、内部リンクの書換え処理です。
現時点では、AMPのページで内部リンクをどこに向ければ良いのか判断が出来ず、また、上記のコードではなんでもかんでもAMP用のパラメータを付けてしまうのでコメントアウトしている状態です。
しかし、仮にAMP対応のページだけ選別できたとしても、URLの書換えには以下のような問題があります。
- AMPページを指定しただけではキャッシュは表示されない
- AMPを利用するサービスごとにキャッシュのURLが違うため固定で指定できない
単純な話で、AMP対応というのは土台でしか無く、実際にキャッシュとしてどう利用されるのかは各サービスごとに違う模様だからです。
キャッシュを利用する側で動的にリンクを書き換えてもらえなければ、サイト側がどれだけがんばろうと「AMPキャッシュからAMPキャッシュへのリンク」は構築できません。
AMPに関しては完成図が見えていないのでこういった部分は判断がつきませが、AMPキャッシュでサイトを丸ごと提供するのが目的の場合、おそらく以下の何れかが作られるのではと考えています。
- サービス側でURLを置換可能なリンク用タグ
- 現状から変えず、AMPページを自動で識別し置換する仕組み
AMPの宣伝以前に明確な完成図を示してもらえると助かるのですが。
現状では、プロジェクトの完成図が提示されていないのにマイルストーンだけが設定されているようで、先を急いで工夫を凝らすと無駄に疲弊するように思えてなりません。
head部分
いろいろ分岐が必要そうなhead部分ですが、前述のようにAMPと非AMPファイルになるべくまとめて分岐させる方法にしています。
なお、構造としては以下のようにしています。
- theme > template > AMP用と非AMP用ファイル
そのため、以下のようなコードになります。
<!DOCTYPE html>
<?php
global $myAmp;
$myAmp = false;
if(check_amp()){
$myAmp = true;
}
?>
<?php if(!$myAmp): ?>
<?php get_template_part( 'template/no-amp-head' ); ?>
<?php else: ?>
<?php get_template_part( 'template/amp-head' ); ?>
<?php endif; ?>
<?php wp_head(); ?>
</head>
<body>
<?php if(!$myAmp): ?>
<amp-analytics type="googleanalytics" id="analytics1">
<script type="application/json">
{
"vars": {
"account": "UA-XXXXXX-Y"
},
"triggers": {
"trackPageview" : {
"on": "visible",
"request": "pageview"
}
}
}
</script>
</amp-analytics>
<?php endif; ?>
解析用の Google Analytics のみbodyタグ以下に設置のためhead内だけではなくなっていますが、概ねこのような感じです。
AMP用のhead
自分用メモなのでサクサク進めますが、AMP用のheadの中身は以下の通りです。
なお、amp-customの部分は仮で適当に書いています。
上記のコードでAMP対応しているAMP用の機能は以下のみです。
- Google analytics
- iframe
- twitter(埋め込み用)
- youtube
- SNSボタン
もっと機能を増やす場合には、それに応じたjsファイルを読み込んでいきますので、サイトによっては相当数のjsが読み込まれることになります。
不要なjsを読み込むとエラーになる
2017年1月にAMPのバリデート内容が変り、不要なjsを読み込むとエラーが出る(正確には今後エラーが出るので直すようにという警告ですが)ようになりました。
例えば以下のような場合は警告がでます。
- Twitterボタンがないのに、Twitter用のjsが読み込まれている
- iframeがないのに、iframe用のjsが読み込まれている
そのため、各ページごとに個別に内容を確認してから、必要なjsをAMP用のhead内に出力しなければなりません。
方法は幾つか考えられますが、私が実装できた方法は以下のページの「amp用の要素があるかどうかチェックして読み込ませるjsを制御する」の節に記載していますので、参考情報として提示します。
上記記事はこの記事より後に作成したAMP対応のファイルのプラグイン時の内容に即していますが、基本的には当記事にも転用できるかと思います。
amp-custom
cssの設定はamp-custom内に記載しますが、上記ではcolor:#333;しか書いていませんので、ここは適宜追加します。
なお、Chromeのエミュレータでの確認ではありますが、以下の動作は確認しました。
- @keyframe
- transform: scale()
- transform: translateX()
- box-shadow
- text-shadow
上記のようなことはあまりメモる必要がないのですが、box-shadowが最初はうまく効かなかったので、一応使えたという記述だけ残しておきたいと思いました。
amp-custom内の画像のパス
amp-custom内に記載する背景画像のなどのパスですが、ベタ書きすると環境が変わる際に面倒なので、以下のようにしています。
<?php $myImagesFolder = get_stylesheet_directory_uri().'/images'; ?>
$myImagesFolderという変数に画像が入っているフォルダまでのパスをいれ、あとは以下のコードで出力しています。
background-image: url(<?php echo $myimagesfolder; ?>/example-bg.jpg);
文字コード
WordPressでは以下の記述で文字コードが出力されますので、テーマによっては以下の記述が記載されています。
<?php bloginfo('charset'); ?>
上記で出力される内容は、WordPress3.5以降では文字コードの表記はUTF-8に固定されており、管理画面では変更できなくなっています。
AMPの場合、大文字のままだと警告がでるようで直接utf-8と書くか、以下のようにコードを変更します。
<meta charset="<?php $charset = get_bloginfo( 'charset' ); echo mb_strtolower( $charset ); ?>">
もっとも、utf-8以外の文字コードにする必要はまずないので、直接utf-8と書いてしまう方がよいかと思います。
非AMP用のhead
AMP対応しないページ用のheadですが、変更点は1点だけでした。
<?php if(is_singular()): ?>
<link rel="amphtml" href="<?php $pageid = get_the_ID(); echo get_permalink($pageid ); ?>?amp=1">
<?php endif; ?
今回はis_singular()でAMPフォーマットの適用を分岐させているため、AMPフォーマットがないページにはrel="amphtml"を向けないように除外しています。
ここを間違うと、AMP対応していないページまでAMPがあると認識されて警告がでたり不具合の原因となりますので、注意が必要です。
プラグイン
プラグインはかなり厄介な問題となる可能性がありそうです。
コアな機能としてプラグインを使っているサイトの場合、AMP対応はかなり厳しくなるかもしれません。
プラグインが読み込む外部スタイルシート
プラグインごとに haed や footer に外部スタイルシートを読み込ませるものがありますが、これが引っかかります。
上記記事内で記載されている方法で除去は可能ですので、概ね以下のような記述になるかと思います(前述の functions.php にはこれを記載しています。)。
add_action( 'wp_print_styles', 'my_deregister_styles', 100 );
function my_deregister_styles() {
if(check_amp()){
wp_deregister_style('yarppWidgetCss');
wp_deregister_style('yarppRelatedCss');
wp_deregister_style( 'wp-pagenavi' );
}
}
当然ですが、これを行うとプラグイン付属のcssが全くなくなってしまうので、必要に応じてプラグインのcssをまるまるか、それともカスタムした形でheadeのamp-custom内に記載する必要があります。
重要なのはどのプラグインをAMPで使うかという点です。
使わないものは消すだけで良いですが、使うものはcss記述を移植せねばなりません。
プラグインが出力するインラインcss
wp_enqueue_styleが使われていれば上記の対処が可能ですが、インラインで css を出力するタイプには対応できません。
プラグインごとにフックが用意されていれば手はあるかもしれませんが。
例として Broken Link Checker を挙げますが、一応内部をみればremoveできるフックはあります。
remove_action('init', 'blc_init', 2000);
上記の記述を加えれば消えはしますが、AMPのチェック関数が働くタイミングではremoveできないようです。
分岐をせずにという方法であれば出来ますが、ここまでするべきなのかどうか。
必須のプラグインでない場合は、使用を中止することも視野に入れた方が良いかと思います。
プラグインの有効化を分岐で制御する
AMPに限らずモバイル対応時もそうですが、プラグイン自体の有効化を特定の条件によってコントロールしたい場合はそれなりにあります。
一応該当する情報はありますので以下の記事を参照すれば可能かと思います。
ページ種別による分岐であれば、この記事の作者の方が作られた以下のプラグイン(上記記事中に紹介があります)を用いれば実現可能な模様です。
この仕組みを改造すれば良いのですが、私ではプラグイン関連は難しく断念しました。
参考サイト
本記事内にある参考サイトをまとめたいと思います。
- The AMP Validator
- AMPをワードプレスにプラグイン無しで設定する方法
- 【WordPress】プラグイン無しでAMP(Accelerated Mobile Pages)に対応にする手順
- AMPの対応方法まとめ (作成途中)
- AMP by Example
- AMP – Accelerated Mobile Pages
- amp-social-share
- [WordPress] WordPress 4.6 からヘッダーに表示されるようになった DNS プリフェッチを非表示にする
- WordPressで「特定のURLが含まれたiframe動画」のみをレスポンシブ表示する方法
- WordPressでプラグインによって読み込まれる外部スタイルシート&javascriptを削除する
- WordPress プラグインロードに条件分岐を使い高速化する方法
- Plugin Load Filter
冒頭に記載していますが、本記事を見るぐらいなら参考サイトのほうをご覧頂いた方がよいです。
結び
現時点ではここまで。
メモるのにも疲れましたが、メモることで見直せた部分も多々あったので、苦労の甲斐はあったように思います。
AMPを触っていて本質的な部分に対する疑問や懸念も生まれましたが、その辺りは機会があれば別の記事で触れたいと思います。
…しかし、自分のサイトながら読みにくいなと思うので、今年中になんとかリニューアルしたいところです。まったく目処はたっていませんが。
※あまりにも見辛かったので突貫リニューアルしました。
派生版
AMP対応用の分岐構造に関して、この記事とは少しだけ違う派生版も考えました。
その部分は以下の記事でご覧いただけます。
なお、AMPのファイルを一つにまとめてプラグイン化する方法も試しました。現在はこちらの方法で当ブログをAMP対応さてせいます。
0人がこの記事を評価
役に立ったよという方は上の「記事を評価する」ボタンをクリックしてもらえると嬉しいです。
連投防止のためにCookie使用。SNSへの投稿など他サービスとの連動は一切ありません。
はじめましてm(__)m。
AMP化に関してもの凄く参考にさせて頂きました。
ありがとうございます。
メモ2、メモ3とありますが、メモ1のこちらの方法にてAMP化?(AMP対応)してみました。
そこで、お忙しいところ大変申し訳ありませんが、
カエレバにてアフィリエイトリンクを作成した際のページにてどうしてもエラーが出てしまいます。
カエレバ・ヨメレバにて作成したページにてもAMPでのエラーがなくなるように変換(置換?)を試しててはみたもののどうしてもエラーが減らすことが出来なくて…。
カエレバ・ヨメレバにて作成したリンク先が含まれるページにてもAMP化でエラーなく表示させる置換方法を教えていただけましたらと思い、コメントさせて頂きました。
大変恐れ入りますが、
置換方法(置換の記述?)を追記もしくはご返信にて、
何卒ご教授お願い申し上げます。
P・S)当サイトでカエレバのリンクがある投稿ページは以下になります。
http://izu.wpblog.jp/post-3961/
また、
AMP化の備忘録として色々と試行錯誤したまとまっていない記事がこちらの投稿をリンクさせて頂いています以下のURLになります。
http://izu.wpblog.jp/post-3897/
Twitterでご返信させていただきましたが、一応記録としてこちらにも要点だけ記載します。
・AMPバリデーターで箇所をよく確認する
・参考サイト(http://nelog.jp/wordpress-content-to-amp)の置換を試す
以上です。