WordPressの投稿本文をAMP化する方法

先日、自作のWordpressテーマをAMP化しました。

その時に、一番苦労したのが、Wordpress本文にある「AMP仕様から外れた記述」を無理やりにでも「AMP仕様に沿った記述」に変更する処理です。

で、自分のサイトも、今回使用する「本文AMP化関数」を使用するようになってから、Google Search Consoleのエラーもなくなったので、備忘録がてら書き残しておこうと思います。

以下で紹介する方法は、あくまで投稿本文のみを出来る限りAMP化する方法で、100%AMP化出来るわけではありません。テーマ自体を完全にAMP化するには、テンプレートファイルの編集も必要になると思います。
当記事に書かれていることを参考に、本文のみをAMP化したとしても、テーマ自体にエラーがあると意味がありません。あくまで(僕の経験上)AMP化で一番面倒だった、本文文章AMP化の参考資料程度に思っていただければ幸いです。
スポンサーリンク
レクタングル(大)広告

投稿本文をAMP化する関数

とりあえず、投稿本文自体をAMP化するのに必要なコードは以下になります。functions.php等に貼り付けて利用します。

このコードをfunctions.phpに貼り付けで、投稿ページURLに「?amp=1」もしくは「&amp=1」を付加してブラウザで開けば、とりあえず投稿ページの本文だけはある程度AMP化された状態で出力されると思います。

参考 【WordPress】プラグイン無しでAMP(Accelerated Mobile Pages)に対応にする手順 | Creator Clip

コードを簡単に説明

以下では、先程紹介したコードについて簡単に説明したいと思います。

AMP判別関数

is_amp()関数は、AMP判別関数となっています。

single(投稿)ページかつ、ampパラメータに1が入っているかを確認して、現在表示しているページがAMPページかどうかを判別します。

余計なHTML属性を取り除く

上記のコード部分で、AMPで使用できないHTML属性を取り除いています。

とりあえず、現状以下の属性を除外しています。

  • style
  • target
  • onclick
この他にも、使用できないHTML属性を利用している場合は、除外処理を追加する必要があります。

使用できないHTML要素を取り除く

AMPで使用できないHTML要素も取り除きます。

この他にも、AMPで使用できないHTML要素は除外処理を追加する必要があります。

ヨメレバ・カエレバの画像にwidth、height属性を加える

多くのブログなどで利用されている、ヨメレバカエレバブログパーツの商品サムネイルもできる限り表示するように期間をしました。

上記コードでは、imgに対してAMPで必要なwidth、heightを付け加えています(ヨメレバやカエレバの出力タグにはサイズ属性がないので)。

ただし、商品のサムネイル画像は、縦長か横長画像なのか等のサイズ情報はありません。なので、サイズ情報は縦75px、横75px一律にしています。

画像をアマゾンから取得して、サイズ情報を取得すればできないこともないかもしれません。けれど、サーバーの設定が必要だったり、画像取得するには時間がかかったり、Amazonサーバーへの負荷なども考えるとリモートからの画像取得は行わないほうが無難かと思います。

ちなみに、こういったブログパーツなどは、前述のstyle属性を取り除く処理によって、インラインスタイルも取り除かれて表示が崩れると思います。

そういった場合は、ブログパーツのクラスに対して、以下のようなスタイルを指定してやる必要があるかもしれません。

画像タグをAMP用に置換

上記コードは、imgタグをamp-imgタグに置換しています。

SNS埋め込みコードをAMP用に置換

各種SNSサービスの埋め込みコードをAMP用に置換しています。

ちなみに、各種SNSサービスの埋め込みコードを実際に表示させるためには、ヘッダーで以下のスクリプトが読み込まれている必要があります。

その他にも、表示させたいSNS埋め込みがあれば、その都度対応させる必要があるかもしれません(AMPの方で対応していないと利用できませんが)。

「SNS埋め込みコードの置換コード」の最後の方で、iframeをamp-iframeに変換していますが、こちらも、width、height属性が指定していないとAMPエラーになると思います。加えて、srcにhttps://が指定してある必要もあります。

余計なスクリプト呼び出しを取り除く

最後に、余計なスクリプト呼び出し(scriptタグ)を本文からすべて取り除いています。

まとめ

今回の「投稿本文をAMP化するコード」は、まだ完璧ではないかもしれません。

ただ、Wordpressで投稿本文をAMP化するするための、ある程度の目安にはなるかと思います。

今回の関数は、かなり、正規表現を使って置換をしているので比較的重い処理になるかと思います。けれど、しっかりとAMP化された暁には、AMPページが、AMP CDNにキャッシュされて置かれ、そこから表示されると思うので、あまり気にする必要もないのかなと。

『WordPressの投稿本文をAMP化する方法』へのコメント

  1. 名前:かなおか 投稿日:2016/11/11(金) 10:50:42 ID:53e834693

    記事を拝見しました。
    非常に勉強になりました。

    ただ、私のようなプログラム知識の浅い者には、投稿本文のみをAMP化するとどうなるのかがイメージできないので、そのあたりお伺いできますでしょうか。

    投稿ページ(記事ページ)のみがAMP化されて、そのほかのページ(トップページ、固定ページ、カテゴリページなど)は通常通りになり、スマホでのGoogle検索結果でも投稿ページのみがAMPとしてインデックスされるのでしょうか?

    それとも、スマホでのGoogle検索の結果でもあくまで通常通りインデックスされ、実際の表示でも本文のみがAMP化されて表示速度が早く、それ以外のリンクやコンテンツは通常通りの表示になるのでしょうか?

    上記の観点から、投稿本文のみをAMP化するとどうなるのか教えて頂けますと幸いでございます。

  2. わいひら 名前:わいひら 投稿日:2016/11/11(金) 12:17:13 ID:fa230c84c

    投稿ページ(記事ページ)のみがAMP化されて、そのほかのページ(トップページ、固定ページ、カテゴリページなど)は通常通りになり、スマホでのGoogle検索結果でも投稿ページのみがAMPとしてインデックスされるのでしょうか?

    ページ全体がAMP化されているのならばそんな感じです。AMPエラーがない投稿ページは、キャシュされ表示が速くなります。ただ、当記事で書かれていることを実施しても、本文自体に取り除けないAMPエラー要因があればその都度修正する必要があります。
    また、Wordpressの場合は、テーマ自体にAMPエラーがある場合も修正する必要があります。

    投稿本文のみをAMP化するとどうなるのか教えて頂けますと幸いでございます。

    本文のみをAMP化したとしても、他にエラーがある場合は全く意味はないと思います。Wordpressテーマ自体に1つでもエラーがあるとキャッシュされません。
    この記事は、WEB制作者がPHPで自サイトの本文をAMP化するときに参考になればと書きました(僕の経験では一番大変だった部分なので)。
    なので、プログラムに慣れておらず、手っ取り早くAMP化したい場合は、、AMP化プラグインもしくは、WordPressのAMPデザインテンプレートを使った方が楽かもしれません。

    でも確かに、書かれていることがややこしいかもしれないので、冒頭に追記で説明を加えておきました。

  3. 名前:izu 投稿日:2016/11/22(火) 08:04:11 ID:c5eed6999

    わいひら様。
    非常に参考にさせて頂いています。

    そこで、うかがいたいのですが、AMP判別関数をphpテンプレート内でエラーが出る度にテンプレート内ではampの時と通常の時でスマホとPCで表示を分けるみたいに分岐条件で対応可能です。

    ですが、
    テーマのスタイルシートなどがfunction内でwp_enqueueによって出力されている場合は、
    テンプレートで分岐することができません。

    function.php内で、

    <?php if(!$myAmp): ?>
    <?php else: // 通常ページの場合 ?>
    <<?php endif; // AMP分岐終了 ?>

    のようにするにはfunction内でどのように記述したら良いのでしょうか?

    お忙しい中大変恐れ入りますが、
    何卒ご教授よろしくお願い申し上げます。

  4. わいひら 名前:わいひら 投稿日:2016/11/22(火) 13:23:48 ID:6fb0fb4bb

    僕の場合は、ヘッダーなどでスクリプトを読み込まないように、完全に以下のようにsingle.phpをsingle-amp.phpとsingle-page.phpといったようにテンプレートを切り分けています。
    https://github.com/yhira/simplicity2/blob/master/single.php

    で、single-amp.phpテンプレート上で、1からスクリプトを読み込まないテンプレートを作っています。
    https://github.com/yhira/simplicity2/blob/master/single-amp.php

    他にも、手はあると思うのですが、これが最もコードが複雑化せずにかけると思ったのでこのようにしています。

  5. 名前:izu 投稿日:2016/11/22(火) 17:15:42 ID:c5eed6999

    わいひら様。
    早速のご返信誠にありがとうございます。

    同じように考えて、
    コメントさせていただく前に、
    amp用に別のテンプレートを現在のsingle.phpをコピーしてsingle-amp.phpとしてやってみたのですが、function.phpでの分岐の記述がいけなかったのかエラーで真っ白になってしまいました。

    以下の3点再度伺わせてください。

    (1)
    この方法ですと、
    この記事に記載されているコードはfunction内に記述する必要はないのでしょうか?

    (2)
    githubに記載されている分岐条件のみの記載で大丈夫でしょうか?

    (3)
    この方法にて行う場合にはテンプレートファイルは小テーマフォルダ内にアップロードすれば良いのでしょうか?

    お忙しい中本当にすみません。
    以上3点教えて頂きたいです。
    どうぞよろしくお願い申し上げます。

  6. わいひら 名前:わいひら 投稿日:2016/11/22(火) 17:26:44 ID:6fb0fb4bb

    それらについては、使用テーマによりけりだと思います。
    何よりもまず、「エラーで真っ白」という状態だけだと、エラーメッセージが表示されていないことになるので、どの部分でエラーが出ているのかわからないので、修正のしようがないのではないかと思います。
    以下の方法で、エラーメッセージを表示させるなどする必要があると思います。
    WordPressでエラーを表示させる方法 | アイビースター

    ただ、本番環境で直接編集するとあまりよろしくないので、できればローカル環境構築してカスタマイズすることをおすすめします。
    Instant WordPressで超簡単にワードプレスローカル環境を構築する方法

    ただ、もしエラーメッセージがわかって、貼り付けていただいても、僕側からは「実際にどういったコードを書いて、どのようにカスタマイズしているか」や、「使用テーマの仕様について熟知しているわけではない」という理由から、質問の内容に付いて答えられないと思います。

    通常のテーマであれば、2、3の質問については、そうですと言いたいところですが、やはりテーマによりけりだと思います。

  7. 名前:izu 投稿日:2016/11/22(火) 19:23:07 ID:c5eed6999

    わいひら様。
    ご返信ありがとうございます。

    かしこまりました。

    なんとか途中まではきているのですが(それでもAMP時エラー30ですが…。(内初めの質問に書かせていただいたヘッダー内jsへのリンクとCSSのリンクがいくつかです)、
    しばらくは、このままで様子を見てみます。

    あっ、
    最後に1つだけ伺わせてください。m(__)m

    functionからwp_enqueueによって出力されているcssとjsファイルは、
    最終手段としてheader.php内に直書きしても問題ないでしょうか?

    もっと勉強してがんばってやってみます。

    お忙しいところ本当に申し訳ありません。

  8. 名前:izu 投稿日:2016/11/22(火) 19:36:51 ID:c5eed6999

    わいひら様。
    度々申し訳ございません。

    headerに直書きしてもプラグインで出力されるjsやcssは吐き出されてしまいますからやはり、
    厳しいですよね…。

    う~ん、
    やっぱり、templateを別に作成して分岐してが一番の得策ですね。

    もう少し頑張ってみたいと思います。

    この度は、
    本当にありがとうございます。

  9. わいひら 名前:わいひら 投稿日:2016/11/22(火) 20:14:22 ID:6fb0fb4bb

    直書きしても良いですが、おっしゃるようにプラグインのリソース出力を制御しなくてはなりません。

    ヘッダーのスクリプト呼び出しや、スタイル呼び出しを制御する場合は、script_loader_tagフックと、style_loader_tagフックの関数で、return null;とでも返すようにすれば、除外できるのではないかと思います。多分。
    フックの使い方は、フック名で検索するといくつか出てくると思います。

    実際にコードを書いて試してみたわけではないので、うまくいくかわからないのですが、よかったら試してみてください。