tamakipedia

鎌倉でフロントエンドエンジニアをしています。Wordpress/Javascript/JQuery が得意で、現在React勉強中です!

【amp】amp研究日記② 〜wordpressコーディングの全体の流れ〜

amp対応日記二日目
今日はamp用のテンプレートを実際に作成していきます。

前回の記事はこちらです。
okinawanpizza.hatenablog.com

今回も独断と偏見がすごいです。(笑)

ampページのurlを作成

今回、テンプレートを切り分ける方法として記事のurlに「amp=1」
と言うパラメーターがある場合のみ AMP化しようと思います。

https://tamakipedia/kijione?amp=1

こんな感じになります。

AMPの存在を知らせるLinkタグを追加する

まず、amp対応ページの在処を示す必要があります。
なので正規の記事ページに以下のリンクがある状態にします。

<link rel="amphtml" href="(記事のurl)?amp=1">

したがってfunctions.phpに以下の記述をします。

add_action('wp_head', 'amp_link_tag');
function amp_link_tag(){
    if(is_singular('post')){
        echo '<link rel="amphtml" href="'.esc_url(get_permalink()).'?amp=1">'."\n";
    }
}

add_actionというのが、アクションフックと呼ばれるらしく
この場合wp_headが呼ばれるタイミングで関数を呼び出すことができます。

AMP専用のテンプレートに切り替える

AMPタグを追加したら、次は amp=1が追加されたらamp専用のテンプレートに切り替えれるように
functions.php に記述を追加します。

function is_amp(){
  //AMPチェック
  $is_amp = false;
  if ( empty($_GET['amp']) ) {
    return false;
  }

  //ampのパラメーターが1かつ投稿ページの
  //かつsingleページのみ$is_ampをtrueにする
  if(is_single() &&
     $_GET['amp'] === '1'
    ){
    $is_amp = true;
  }
  return $is_amp;
}

そして記事の表示部分は

//single.php
<?php if(is_amp()) : ?>
  <?php if ( have_posts() ) : ?>
    <?php while ( have_posts() ) : ?>
      <?php the_post(); ?>
      <?php get_template_part('/amp/single-amp'); ?>
    <?php endwhile; ?>
  <?php endif; ?>
<?php else : ?>
  <?php get_template_part('/amp/single-page'); ?>
<?php endif; ?>

このような形で single-amp.php と single-page.php を出しわけするように記述しました。
(single.phpそのものを読み込まずに、amp用のテンプレートを呼び出す方法もあるらしいです!!)

single-page.php テンプレートの作成

ここまでで、「(通常の記事url + ?amp=1)」で
googleがampページとしてクロールしてくれるようになり、
かつ、single-amp.php というアンプ専用のテンプレートを呼び出してくれることになりました。

次は single-page.phpの中身です。

テンプレートは以下の二点によって処理方法が違ってきます。
①静的な部分(ヘッダー、フッターなどの変わらない部分)
②動的な部分(記事の内容など、ページごとに変わってくる部分)

静的部分

ampのドキュメントを見る感じ静的部分の方がテストしやすそうなので
こちらから進めていきました。
これに関してはamp html 用のテンプレートが記載されているので
メディアのヘッダー部分をこちらのテンプレートに当てはめて実装していきました。

・テンプレート
(って絵文字が使われててめっちゃかっこいいですよね笑)

<!doctype html>
<html ⚡>
  <head>
    <meta charset="utf-8">
    <title>Sample document</title>
    <link rel="canonical" href="./regular-html-version.html">
    <meta name="viewport" content="width=device-width">
    <style amp-custom>
      h1 {color: red}
    </style>
    <script type="application/ld+json">
    {
      "@context": "http://schema.org",
      "@type": "NewsArticle",
      "headline": "Article headline",
      "image": [
        "thumbnail1.jpg"
      ],
      "datePublished": "2015-02-05T08:00:00+08:00"
    }
    </script>
    <script async custom-element="amp-carousel" src="https://cdn.ampproject.org/v0/amp-carousel-0.1.js"></script>
    <script async custom-element="amp-ad" src="https://cdn.ampproject.org/v0/amp-ad-0.1.js"></script>
    <style 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>body{-webkit-animation:none;-moz-animation:none;-ms-animation:none;animation:none}</style></noscript>
    <script async src="https://cdn.ampproject.org/v0.js"></script>
  </head>
  <body>
    <h1>Sample document</h1>
    <p>
      Some text
      <amp-img src=sample.jpg width=300 height=300></amp-img>
    </p>
    <amp-ad width=300 height=250
        type="a9"
        data-aax_size="300x250"
        data-aax_pubname="test123"
        data-aax_src="302">
    </amp-ad>
  </body>
</html>

AMP HTML 仕様 - amp.dev

ちょこちょこ細かいルールはありますが、
今回は割愛させていただきます。

動的な部分

こちらはコンテンツの数だけ対応していかなきゃいけないので難しい印象があります。
こちらに関しては functions.php の中に記述して、
コンテンツの中のampで使えないタグをfunctions.php でamp用のタグに加工する必要があります。
こちらは何度もテスト確認する必要ありです、、、
現在進行形ですごく時間がかかっているところになります。

add_filter('single_template', 'change_amp_template');
function change_amp_template($single_template){
    $change_template = $single_template;
    $post = get_queried_object();
    $string = $post->post_content;
    if(isset($_GET['amp']) && $_GET['amp'] == 1){
        //本文内の要素をAMP用に置換したり、不要なものは削除する
        add_filter( 'the_content', 'the_content_filter', 12 );
        function the_content_filter( $content ) {

            //ここからampで使えないタグをphp側からどんどん書き換えていく処理を追記していきます

single_templateフィルターフックというのがあり、
いわば記事の詳細テンプレートが読み込まれる際に処理をさせるそうです。

    if(isset($_GET['amp']) && $_GET['amp'] == 1){

urlを読みに行って、もし 「amp」パラメーターが「1」だったら
次の処理をする、というようなコード。

        add_filter( 'the_content', 'the_content_filter', 12 );

the_content()は管理画面に入力した記事内容を出力するテンプレートタグで、
こちらのコードはthe_content()が呼び出される際に「the_content_filter」という処理を実行します。。という処理です。