最近「サイトをAMP対応してくれ!」という案件が増えてきた。
AMPページはオリジナルのJavaScriptが使えなかったり、AMPページ用のHTMLタグを使わないといけなかったりと、慣れていないコーダーにとっては面倒に感じることが多い。
中でも筆者が面倒に感じているのはCSSの制限である。
通常ページ用のCSSをそのまま流用しようとすると、
「“!important”は使っちゃダメ!文字コードは入れちゃダメ!“@import”で外部ファイルを読み込むのもダメだし、容量が50KBを超えるなんてとんでもない!」と、AMPテスターにとにかく怒られまくる。
しかし、毎度毎度CSSの中身を確認・修正してたら工数掛かりすぎだし、ルーチンワークは避けたいというのがエンジニアのさがである。
そこで考えた。
通常ページ用のCSSから使ってはいけないプロパティだけ削除しAMPページに出力。崩れた部分だけ後で修正すれば良い。
そうすれば通常ページのCSSに修正が発生しても、AMPページにもそのまま反映される。
今回は記事のタイトル通り、WordPressサイトでの話。
なのでPHPを使ってその辺をやってしまおう。
そんなこんなでできたコードがこちら。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
<?php // 通常テーマCSS ob_start(); include_once(dirname(__FILE__) . '/../style.css'); $sp_css = ob_get_contents(); ob_end_clean(); // WordPressのプラグイン用CSS ob_start(); $document_root = $_SERVER["DOCUMENT_ROOT"]; include_once($document_root . '/wp-content/plugins/xxxxx/css/xxxxx.min.css'); $plugins_css = ob_get_contents(); ob_end_clean(); // 通常ページ用のCSSをまとめる $sum_css = $sp_css . $plugins_css; // コロンの後の空白を削除する $sum_css = str_replace(': ', ':', $sum_css); // タブ、スペース、改行などを削除する $sum_css = str_replace(' {', '{', $sum_css); $sum_css = str_replace(array("\r\n", "\r", "\n", "\t", ' ', ' ', ' '), '', $sum_css); // AMP対策(!important、文字コード、@importなど削除) $sum_css = str_replace('!important', '', $sum_css); $sum_css = str_replace('@charset "UTF-8";', '', $sum_css); $sum_css = preg_replace('/(@import url\(".*?"\);)/', '', $sum_css); // CSSのimgをamp-imgに書き換え $sum_css = str_replace(' img{', ' amp-img{', $sum_css); // CSSの画像ソースURL書き換え $template_directory_uri = 'url("' . get_template_directory_uri() . '/assets/'; $sum_css = str_replace('url("../', $template_directory_uri, $sum_css); $template_directory_uri = 'url(' . get_template_directory_uri() . '/assets/'; $sum_css = str_replace( 'url(../', $template_directory_uri, $sum_css ); // AMP専用CSS ob_start(); include_once(dirname(__FILE__) . '/style-amp.css'); $amp_css = ob_get_contents(); ob_end_clean(); // コメント削除 $amp_css = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $amp_css); // コロンの後の空白を削除する $amp_css = str_replace(': ', ':', $amp_css); // タブ、スペース、改行などを削除する $amp_css = str_replace(' {', '{', $amp_css); $amp_css = str_replace(array("\r\n", "\r", "\n", "\t", ' ', ' ', ' '), '', $amp_css); $sum_css = $sum_css . $amp_css; // その他CSSの容量削減・AMPエラー対策のために個別削除があれば $sum_css = preg_replace('/(\.l-contact.*?})/', '', $sum_css); echo $sum_css; |
順に解説していこうと思う。
そもそも「AMP用テーマの作り方からわからない!」という方へ
本来の趣旨から少し外れてしまうが、一応説明を。「そこまではもうやってる」という方はこの章は飛ばしていただきたい。
まずAMPページの実装方法だが、筆者はWordPress用のAMPプラグインを使い、通常のページのURLに“/amp”をつけるとAMPページが存在する、という現在主流の方法を使っている。
テーマ構造は、通常のテーマの中にAMP用テーマを配置している形。
通常テーマの中に“_amp”というディレクトリを作り、“wp-content/plugins/amp/templates”にあるファイル一式をコピーして持ってくる。
このファイルたちを編集していく形である。
通常テーマの“function.php”の中に
1 |
get_template_part( '_amp/functions' ); |
と記述。
そして“/amp”にfunction.phpを作り、
1 2 3 4 5 6 7 |
function xyz_amp_set_custom_template( $file, $type, $post ) { if ( 'single' === $type && did_action( 'pre_amp_render_post' ) !== 0 ) { $file = dirname( __FILE__ ) . '/single.php'; } return $file; } add_filter( 'amp_post_template_file', 'xyz_amp_set_custom_template', 10, 3 ); |
と記述。上記の場合「singleページかつAMPページだったら“/amp/single.php”を読み込んでね」という指示なので、AMP対応させたい範囲に応じて変更して欲しい。
色々な実装方法を探したが、これが最も美しく管理できると思う。
ここまでは筆者も開拓者の方々を真似させていただいた身である。
CSSの中身を修正処理を行うPHPファイルの設置場所
AMPプラグインを使ってAMP対応をしている場合、<head>タグ内に以下のような記述をしていると思う。
1 2 3 4 |
<style amp-custom> <?php $this->load_parts( array( 'style' ) ); ?> <?php do_action( 'amp_post_template_css', $this ); ?> </style> |
上記を以下のようにし、“style.php”の中で修正処理を行う。
1 2 3 4 |
<style amp-custom> <?php include( dirname( __FILE__ ) . '/style.php' ); ?> <?php do_action( 'amp_post_template_css', $this ); ?> </style> |
最初に提示したコードの説明
それではいよいよコードの説明。
見やすいようにわざと1つの処理を2処理に分けている部分もあるが、わざとなので馬鹿にしないで欲しい。
1 2 3 4 5 |
// 通常テーマCSS ob_start(); include_once( dirname( __FILE__ ) . '/../style.css' ); $sp_css = ob_get_contents(); ob_end_clean(); |
まずは通常ページ用のCSSを読み込み。
普通に読み込もうとしても無理なので、バッファリングを用いる。
1 2 3 4 5 6 |
// WordPressのプラグイン用CSS ob_start(); $document_root = $_SERVER["DOCUMENT_ROOT"]; include_once( $document_root . '/wp-content/plugins/xxxxx/css/xxxxx.min.css' ); $plugins_css = ob_get_contents(); ob_end_clean(); |
次にWordPressのプラグイン用CSSも読み込み。
投稿ページの見た目を豪華にするプラグインなどをAMP用ページでも適用させたい場合のみ必要。
1 2 |
// 通常ページ用のCSSをまとめる $sum_css = $sp_css . $plugins_css; |
で、これらを一旦まとめる。
1 2 3 4 5 |
// コロンの後の空白を削除する $sum_css = str_replace(': ', ':', $sum_css); // タブ、スペース、改行などを削除する $sum_css = str_replace(' {', '{', $sum_css); $sum_css = str_replace(array("\r\n", "\r", "\n", "\t", ' ', ' ', ' '), '', $sum_css); |
次に余計な空白などを削除。圧縮と似たようなことをPHPでやっている。
これは容量削減のほかに、この後行うCSS修正処理の際、表記ゆれによって処理から外れてしまう記述が出てくるのを避ける目的もある。
1 2 3 4 |
// AMP対策(!important、文字コード、@importなど削除) $sum_css = str_replace('!important', '', $sum_css); $sum_css = str_replace('@charset "UTF-8";', '', $sum_css); $sum_css = preg_replace('/(@import url\(".*?"\);)/', '', $sum_css); |
そしてやっと禁止プロパティの削除。
冒頭で挙げた禁止プロパティを、正規表現を使いつつ空欄に置き換えている。
1 2 |
// CSSのimgをamp-imgに書き換え $sum_css = str_replace(' img{', ' amp-img{', $sum_css); |
更に、<img>タグに直接CSSを当てている部分もあると思うので、これを<amp-img>に変更。
この処理は行わない方がデザインが崩れない場合もあると思うので、必要に応じて使っていただきたい。
1 2 3 4 5 |
// CSSの画像ソースURL書き換え $template_directory_uri = 'url("' . get_template_directory_uri() . '/assets/'; $sum_css = str_replace('url("../', $template_directory_uri, $sum_css); $template_directory_uri = 'url(' . get_template_directory_uri() . '/assets/'; $sum_css = str_replace( 'url(../', $template_directory_uri, $sum_css ); |
先に述べたように、ディレクトリ階層が通常ページ用のCSSより一階層下のため“background-img”などで指定されている画像が読み込めなくなっている。
それらをAMPページでも問題なく読み込めるよう、ディレクトリ指定を書き換えている。
一応表記ゆれ対策として、ダブルクォーテーションでもシングルクォーテーションでも対応するようにしてある。
ここも構造に合わせて編集していただきたい。
1 2 3 4 5 |
// AMP専用CSS ob_start(); include_once(dirname(__FILE__) . '/style-amp.css'); $amp_css = ob_get_contents(); ob_end_clean(); |
その後、AMPページ用のCSSを読み込み。
これは通常ページ用のCSSをもろもろ削除したことや、AMP用JSを使うことによって崩れた部分を修正するためのCSSである。
“style.php”と同じ階層に“style-amp.css”を設置している。
1 2 3 4 5 6 7 |
// コメント削除 $amp_css = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $amp_css); // コロンの後の空白を削除する $amp_css = str_replace(': ', ':', $amp_css); // タブ、スペース、改行などを削除する $amp_css = str_replace(' {', '{', $amp_css); $amp_css = str_replace(array("\r\n", "\r", "\n", "\t", ' ', ' ', ' '), '', $amp_css); |
そしてこちらも圧縮し、容量削減。
1 |
$sum_css = $sum_css . $amp_css; |
通常ページ用CSSとAMPページ用CSSをまとめる。
1 2 |
// その他CSSの容量削減・AMPエラー対策のために個別削除があれば $sum_css = preg_replace('/(\.l-contact.*?})/', '', $sum_css); |
その他容量制限に引っかかりそうだったら、消せそうなCSSを削除。
ここでは例としてコンタクトページ用のCSSをまとめて削除している。
ここはCSSの記述の仕方によるので、使えそうだったら使ってほしい。
弊社はSassを用い、ページごとに親クラスを作っているのでこういった方法で削減している。
1 |
echo $sum_css; |
で、最後にCSSを“echo”。
おわりに
以上、まだまだ改良できる部分はあると思うがいかがだっただろう。
未熟なりに工夫してみたつもりである。
「PHPで正規表現を使うと重くなる」なんて話も聞くが、AMPページはキャッシュされるのが前提なので問題ないと思われる。
もっと良い方法もあると思うので今後も精進したい。