QOXホームへ

WordPressをAMP対応

Yuko Hashimoto

Yuko Hashimoto

ここ数年は7月に必ず皮膚炎で病院に駆け込む橋本です。もう限界です。
みなさま、熱中症にも夏バテにも暑さにまつわる諸症状全般にお気をつけください。
私はマスクと腹巻が手放せません。

…それはともかく、
先日のリニューアルでクオックスのサイトもAMPに対応しました。
Wordpressに「AMP」というプラグインを適用させることで対応したのですが、初期設定では寂しい見た目を結構いじったので、その覚え書きです。

AMPとは

AMP = Accelerated Mobile Pages Project。
モバイル向けの高速表示用HTMLのこと。HTMLをGoogleにキャッシュし読み込み時間を大幅に削減する仕組みだそうです。
詳しくは公式サイトをご覧ください。
AMPプロジェクト(公式サイト)

AMPサイトでは多くの制限があります。

  • JavaScriptは原則使用不可
  • 外部ファイルの読み込み不可。公式のホワイトリストに登録されたものは読み込み可能
  • CSSはheadタグ内に記入し50KB以下。!importantは使えない
  • imgやiframeは専用タグに置き換え
  • Analyticsや広告もAMP対応のタグに置き換え

リッチなサイトにはきつい感じですが、テキストベースの記事を高速に表示するためのものなので仕方ないっぽい。

プラグイン入れてみた

その名もずばり「AMP」というプラグインを入れてみました。
AMP – WordPress Plugins

通常ページURLの末尾に「/amp」をつけるだけでAMPに変換したページを表示してくれます。
しかし初期設定のテンプレートが非常に寂しい。左が初期設定、右がデザインを元のページに近づけるよう手を入れたものです。

これはいけない。

テンプレートを作る

こちらのサイトを参考にカスタマイズを行いました。
WordPressのプラグインを使ってAMP⚡対応するにあたっての備忘録

テンプレートのファイルを用意

上記サイトからのコピペになります。

<!DOCTYPE html>
<html ⚡>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
<?php do_action( 'amp_post_template_head', $this ); ?>
<style amp-custom>
<?php
$this->load_parts( array( 'style' ) );
do_action( 'amp_post_template_css', $this );
?>
</style>
</head>
<body>
<?php
// 「amp」フォルダ内の「header.php」を読み込む
include ( TEMPLATEPATH . '/amp/header.php'); ?>
<main>
<article>
<?php
echo $this->get( 'post_amp_content' ); //個別投稿の本文を表示する
?>
</article>
</main>
<?php
// 「amp」フォルダー内の「footer.php」を読み込む
include ( TEMPLATEPATH . '/amp/footer.php'); ?>
<?php do_action( 'amp_post_template_footer', $this ); ?>
<footer>
<p>&copy; <?php echo date( 'Y' ); ?> <?php bloginfo( 'name' ); ?></p>
</footer>
</body>
</html>

style.phpは元のデザインに使っているCSSをそのまま使えば良さそうですが、AMPに使用できるスタイルシートの制限が

  • 全体で50KB以下
  • !importantは使用不可

となっているので、なるべく余分な部分を減らした上で、こちらを使って少し圧縮しました。
PHP Function to Minify HTML, CSS and JavaScript – GitHub

php-html-css-js-minifier.phpをstyle.phpを同じフォルダに置いて、style.phpに適用します。

<?php
include 'php-html-css-js-minifier.php';
ob_start();
?>
/*
スタイルシートの中身
*/
<?php
$content = minify_css( ob_get_clean() );
echo $content;
?>

また、ページ内にインライン(style=”color:#000;”みたいな形)でスタイルシートを書くのも禁止されています。
ページ上部でアイキャッチ画像をstyle=”background-image…と直接指定していたので、header.php内でクラスにしてしまいます。
記事ごとにカスタムCSSを設定していたり、AMP用のAnalyticsやAdsenseの設定もあるので、まとめるとこんな感じ。

<!DOCTYPE html>
<html ⚡>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1">
    <?php do_action( 'amp_post_template_head', $this ); ?>

    <?php if( get_option( "qox_analytics" ) ){ ?> // 設定画面でAnalytics設定しているとき
    <script async custom-element="amp-analytics" src="https://cdn.ampproject.org/v0/amp-analytics-0.1.js"></script>
    <?php } ?>

    <?php if( get_option( "qox_adsenseAmp" ) ){ ?>// 設定画面でAdsense設定しているとき
    <script async custom-element="amp-ad" src="https://cdn.ampproject.org/v0/amp-ad-0.1.js"></script>
    <?php } ?>

    <style amp-custom>
    <?php
      $this->load_parts( array( 'style' ) );
      do_action( 'amp_post_template_css', $this );

      // カスタムCSSの内容
      if ( is_page() || is_single() ) {
        if ( have_posts() ) : while ( have_posts() ) : the_post();
          echo get_post_meta(get_the_ID(), '_custom_css', true);
        endwhile; endif;
        rewind_posts();
      }


      // アイキャッチ
      if ( has_post_thumbnail() ) {
         $image_id = get_post_thumbnail_id ();
         $image_url = wp_get_attachment_image_src ($image_id, true);
         echo ' .header{ background-image:url("' . $image_url[0] . '");}';
         echo ' .a_wrapper .image_wrapper .image{ background-image:url("' . $image_url[0] . '");}';
       } else {
         echo ' .header{ background-image:url("' . get_template_directory_uri() . '/images/featured.png");}';
         echo ' .a_wrapper .image_wrapper .image{ background-image:url("' . get_template_directory_uri() . '/images/featured.png");}';
       }
       ?>
    </style>

    <!-- FontAwesome -->
    <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">

  </head>
<body>

  <?php if( get_option( "qox_analytics" ) ){ ?>
  <amp-analytics type="googleanalytics" id="analytics1">
  <script type="application/json">
  // Analyticsの設定
  </script>
  </amp-analytics>
  <?php } ?>

AdsenseやAnalyticsはテンプレートに慣れない管理者でも変更できるよう、会社情報とまとめて設定する画面を作っているので、そちらに設定があれば表示するようにしています。

AMPページでは外部ファイルの読み込みはできませんが、AMP公式に指定されたカスタムフォントは読み込んで使用できます。
カスタム フォントの追加-AMP
2018年7月時点で使用できるのはこれだけですが…。

  • Typography.com: https://cloud.typography.com
  • Fonts.com: https://fast.fonts.net
  • Google Fonts: https://fonts.googleapis.com
  • Typekit: https://use.typekit.net
  • Font Awesome: https://maxcdn.bootstrapcdn.com, https://use.fontawesome.com

禁止要素、埋め込み要素、画像サイズの指定

AMP内で使用できない要素を削除し、画像にwidthとheightを加えます。こちらも前出のサイトのコピペです。

add_action( 'pre_amp_render_post', 'xyz_amp_add_custom_actions' );

function xyz_amp_add_custom_actions() {
  add_filter( 'the_content', 'my_amp_custom_main_content' );
}

function my_amp_custom_main_content ( $content ) {
  // いろいろ削除
  $content = preg_replace(array(
  '/<script[^<]*?<\/script>/iu', // scriptを削除
  '/style="[^"]*?"/iu', // styleを削除
  '/border="[^"]*?"/iu', // borderを削除
  '/target="[^"]*?"/iu', // targetを削除
  '/onclick="[^"]*?"/iu', // onclickを削除
  '/scale="[^"]*?"/iu' // scaleを削除
  ), '', $content);

  // 画像にサイズ(widthとheight)を追加
  $pattern = '/<img [^>]*?src="(https?:\/\/[^"]+?)"[^>]*?>/iu';
  preg_match_all($pattern, $content, $imgs);
  foreach ( $imgs[0] as $i => $img ) {
  if ( false !== strpos( $img, 'width=' ) && false !== strpos( $img, 'height=' ) ) {
  continue;
  }
  $img_url = $imgs[1][$i]; // 画像url
  $img_size = @getimagesize( $img_url ); // 画像サイズを取得
  if ( false === $img_size ) {
  continue;
  }
  $replaced_img = str_replace( '<img ', '<img ' . $img_size[3] . ' ', $imgs[0][$i] );
  $content = str_replace( $img, $replaced_img, $content );
  }
  // imgタグをamp-imgタグに置換
  $pattern = '/<img ([^>]+?)\/?>/i';
  $replacement = '<amp-img layout="responsive" $1></amp-img>';
  $content = preg_replace($pattern, $replacement, $content);

  // Twitterをamp-twitterに置換する(埋め込みコード)
  $pattern = '/<blockquote class="twitter-(tweet|video)".*?>.+?<a href="https:\/\/twitter.com\/.*?\/status\/(.*?)">.+?<\/blockquote>/iu';
  $replacement = '<amp-twitter width=592 height=472 layout="responsive" data-tweetid="$2"></amp-twitter>';
  $content = preg_replace($pattern, $replacement, $content);
  // YouTubeをamp-youtubeに置換する(埋め込みコード)
  $pattern = '/<iframe[^>]+?youtube\.com\/embed\/(.+?)(\?[^>]+?)?"[^<]+?<\/iframe>/iu';
  $replacement = '<amp-youtube layout="responsive" data-videoid="$1" width="560" height="315"></amp-youtube>';
  $content = preg_replace($pattern, $replacement, $content);
  // ついでにiframeも置換する
  $pattern = '/<iframe ([^<]+?)<\/iframe>/iu';
  $replacement = '<amp-iframe layout="responsive" $1</amp-iframe>';
  $content = preg_replace($pattern, $replacement, $content);

  return $content;
}

// AMPのscriptを制御
add_action( 'amp_post_template_data', 'my_amp_post_custom_add_script');
function my_amp_post_custom_add_script($data) {
  $content = $data['post_amp_content'];
  // YouTube
  if (preg_match('/<amp-youtube[^<]*?<\/amp-youtube>/iu', $content)) {
  $data['amp_component_scripts']['amp-youtube'] = 'https://cdn.ampproject.org/v0/amp-youtube-0.1.js';
  }
  // Twitter
  if (preg_match('/<amp-twitter[^<]*?<\/amp-twitter>/iu', $content)) {
  $data['amp_component_scripts']['amp-twitter'] = 'https://cdn.ampproject.org/v0/amp-twitter-0.1.js';
  }
  // iframe
  if (preg_match('/<amp-iframe[^<]*?<\/amp-iframe>/iu', $content)) {
  $data['amp_component_scripts']['amp-iframe'] = 'https://cdn.ampproject.org/v0/amp-iframe-0.1.js';
  }
  return $data;
}

仕上がり

AMP化されたページはURLの末尾に「/amp」をつけると見ることができます。
この記事のAMP版はこちらです。
http://qox.jp/blog/wordpress-amp/amp/

参考サイト

AMPプロジェクト(公式サイト)
WordPressのプラグインを使ってAMP⚡対応するにあたっての備忘録
WordPressをマジメにAMP(Accelerated Mobile Pages)対応させた話 #AMPlify
AMP – WordPress Plugins
PHP Function to Minify HTML, CSS and JavaScript – GitHub

Yuko Hashimoto

Yuko Hashimoto デザイナー

デザインって何だろう、と悶々としながら、オシャレさん目指して試行錯誤する日々です。ハト好き。寺社と散歩と時代劇が好きです。気がつくと荷物が多くなるのが悩み。

記事一覧
Go up