プラグインを使わずWordPressの固定ページでAMP対応ページを作ってみた

プラグインを使わずWordPressの固定ページでAMP対応ページを作ってみたのアイキャッチ画像

現時点のお話ですが、WordPressプラグインでAMPを実装してみましたが、Structured Data Testing Toolでチェックを行うとエラーがあったので、固定ページを使って自作してみることにしました。

  1. 固定ページのページングでAMPページを生成する
  2. 固定ページのカレントページNoを取得する
  3. 投稿の現在の記事が何番目の投稿か取得する
  4. 投稿のimgをamp-imgに置換する

以上を満たせれば、できるはずです!

WordPressの準備

まず、固定ページをampというスラッグで作成しておきます。下書きで保存すればページIDがわかるのでSEO的に厄介なことにならないように、除外するところは公開する前に除外しておきましょう。とりあえず僕はXML Sitemapの除外をまずしました。

AMP用の固定ページテンプレートと専用のheader.phpとfooter.phpを用意

AMPの仕様に合わせるためにテンプレート一式用意します。ページテンプレートはpage-amp.php、ヘッダー、フッターはheader-2.phpとfooter-2.phpとそれぞれハイフンとナンバリングを付与します。呼び出しは以下の通り。

<?php get_header("2"); ?>
<?php get_footer("2"); ?>

固定ページのページングと現在のページ数

固定ページを1件表示にしてpagedを持たせるようにし、現在何ページか取得できるようにします。

  <?php
  $paged = get_query_var('paged') ? get_query_var('paged') : 1 ;
  $args =	array(
  		'posts_per_page'   => 1, //表示件数
  		'orderby'          => 'date', //ソートの基準
  		'order'            => 'ASC', //DESC降順 ASC昇順
  		'post_type'        => 'post', //投稿タイプ名postは通常の投稿
  		'post_status'      => 'publish', //公開状態
  		'caller_get_posts' => 1, //取得した記事の何番目から表示するか
  		'paged'            =>  $paged //ページネーションに必要
  );
  $wp_query = new WP_Query($args);
  while ($wp_query->have_posts()) : $wp_query->the_post();
  ?>
//処理
<?php endwhile; ?>
<p>
<?php echo $paged; ?>
</p>

echo $paged;に現在のページNoが出力されたので、ここはこれでOK。

header.phpにamphtmlを追加する

通常投稿側にAMPページの存在を知らせるリンクを作る必要がありますので、header.phpに現在の記事が何番目の投稿かを取得してURLを動的にします。

function.phpに投稿Noがわかる関数を追加

投稿Noがわかる関数をfunctions.phpに追加します。フォーラムからコピペさせてもらいました。

  function get_post_number( $post_type = 'post', $op = '<=' ) {
      global $wpdb, $post;
      $post_type = is_array($post_type) ? implode("','", $post_type) : $post_type;
      $number = $wpdb->get_var("
          SELECT COUNT( * )
          FROM $wpdb->posts
          WHERE post_date {$op} '{$post->post_date}'
          AND post_status = 'publish'
          AND post_type = ('{$post_type}')
      ");
      return $number;
  }

通常投稿側のheader.phpにamphtmlタグを追加します。今回のAMPは普通の投稿の詳細ページのみなので、条件分岐を行います。

  <?php if (is_single() && get_post_type() === 'post'): ?>
  <link rel="amphtml" href="<?php echo home_url(); ?>/amp/page/<?php echo get_post_number( $post->post_type ); ?>/">
  <?php endif; ?>

これで仕組みの方はOKなので、後はAMPのマークアップに対応させる作業です。

imgをamp-imgに置換する

AMPではimgタグをamp-imgにしないといけないので、置換します。

  <?php
  function change_obj($obj){
  	$replace = array(
  		'<p class="imagebox"><img ' => '<p class="imagebox"><amp-img layout="responsive" '
  	);
  	$obj = str_replace(array_keys($replace), $replace, $obj);
  	return $obj;
  }
  add_filter('the_content', 'change_obj');
  ?>

置換は問題なく行えましたがそれだけではダメです。AMPでは画像サイズを明示する必要がありますので、僕の場合過去の投稿の画像はちょいちょいやり直す必要があります。

schema.orgの設定

各項目をうまく動的に生成できるように調整します。僕はメタ周りをそれ専用にカスタム投稿タイプを一つ作って管理していますので、サンプルにするにはややこしいので、その箇所は割愛します。

  <script type="application/ld+json">{
	"@context": "http://schema.org",
	"@type": "BlogPosting",
	"headline": "記事タイトル",
	"description": "ディスクリプション",
	"datePublished": "<?php the_time('c'); ?>",
	"dateModified": "<?php the_modified_time('c'); ?>",
	"mainEntityOfPage":{
		 "@type": "WebPage",
		 "@id": "<?php the_permalink(); ?>"
	},
	"publisher": {
		"@type":"Organization",
		"name":"サイト名",
		"logo":{
			"@type":"ImageObject",
			"url":"ロゴのパス",
			"height":32,
			"width":32
		}
	},
	"author": {
		"@type": "Person",
		"name": "オーサー名"
	},
	"image" : {
		"@type" : "ImageObject",
		"url" : "アイキャッチ",
		"width" : 740,
		"height" : 416
	}
}</script>

この時点で一応チェックしておきました!エラーなしです!

スタイル

AMPでは下の記述は必ず必要です。スタイルを当てる場合はamp-customの記述が必要です。

<style>body {opacity: 0}</style><noscript><style>body {opacity: 1}</style></noscript>
<style amp-custom>
//スタイル
</style>
<script async src="https://cdn.ampproject.org/v0.js"></script>

とりあえず実装したページです。詳しくはソース参照。
※2016.02.17にシングルページで実装する方法に変更しましたので、リンク先をそちらに変更しました。

実装してみてわかったこと

AMPはキャッシュされてスマホで高速表示ができるイカしたやつ!ぐらいのイメージしかなくとりあえず実装してみました。実装するために調べてわかったこと、実装してみてわかったこと。結構勉強になりました。

AMPの注意点

  1. AMPは基本jsが使えない
  2. 検索のカルーセルをサポートしているのはNewsArticleとBlogPosting
  3. CSSはインライン
  4. 画像はサイズ指定が必要

レスポンシブとhtml5が主流になって画像のサイズ指定、やらなくなったので地味にこれの対応が一番頭悩ませるポイントになりそうです。まぁサイズ指定してるほうがレンダリングは速いって言われてるし、これを機にまた制作レギュレーションの見直しが必要そうです。