WordPressに移行してAMP HTMLでテーマ「Amplified」を自作しました

これまでHexoを使ってブログを書いていましたが、毎回コマンドラインからビルドしないといけないのと、ブログ更新の間隔が空いた期間にnpmをアップデートしたらHexoがこけたりするようになってうんざりしたので、WordPressへと移行しました。使用するテーマは一からAMP HTMLで書いています。テーマ名は「Amplified」にしてます。WordPressではAMP対応するプラグインがありますが、そちらではAMP用のページを別途吐き出すようになっているだけで、AMP自体の機能を色々使ったりという感じにはなっていません。自作テーマではAMPページしかないので、ちょっとしたことでもAMPコンポーネントを使っていたりします。そのうちちゃんと整理してリリースできるようにしたいです。ということで、以下AMP HTMLに関する雑記です。

AMP HTMLでWordPressのテーマを作成する際の注意点:構造化データは必須

AMP自体は構造化データが埋め込まれていなくてもエラーとして扱われなくなりましたが、検索トップのカルーセルに表示してもらうためには相変わらず構造化データは必須になっています。ブログ記事の場合は記事そのものに関する構造化データ(@type: BlogPostingのもの)と、パンくずリスト用の@typeが”BreadcrumbList”のものが必要になります(パンくずはなくても大丈夫ですが、たいていのWordPressテーマはMicrodataによるマークアップをしているので、自作のテーマでもパンくずについてJSON-LDで構造化データを埋め込んでいます。このページの場合だとこんな感じになってます:

<script type="application/ld+json">
{
    "@context": "http://schema.org",
    "@type": "Person",
    "name": "Yuki Yamashina",
    "url": "https://yukiyamashina.com",
    "sameAs": [
        "https://plus.google.com/116174340363016950926",
        "https://twitter.com/Yuki_Yamashina",
        "https://www.facebook.com/yuki.yamashina.56"
    ]
}
</script>
 
<script type="application/ld+json">
{
    "@context": "http://schema.org",
    "@type": "BreadcrumbList",
    "itemListElement": [
        {
            "@type": "ListItem",
            "position": 1,
            "item": {
                "@id": "https://yukiyamashina.com/blog/category/cms/",
                "name": "CMS",
                "image": "https://yukiyamashina.com/wp-yamashina/wp-content/themes/amplified/images/ionicons/cms.svg"
            }
        },
        {
            "@type": "ListItem",
            "position": 2,
            "item": {
                "@id": "https://yukiyamashina.com/blog/category/cms/wordpress/",
                "name": "WordPress",
                "image": "https://yukiyamashina.com/wp-yamashina/wp-content/themes/amplified/images/ionicons/wordpress.svg"
            }
        }
    ]
}
</script>
 
<script type="application/ld+json">
{
    "@context": "http://schema.org",
    "@type": "BlogPosting",
    "mainEntityOfPage": {
        "@type": "WebPage",
        "@id": "https://yukiyamashina.com/blog/2016/10/09/wordpress%e3%81%ab%e7%a7%bb%e8%a1%8c%e3%81%97%e3%81%a6amp-html%e3%81%a7%e3%83%86%e3%83%bc%e3%83%9e%e3%82%92%e8%87%aa%e4%bd%9c%e3%81%97%e3%81%be%e3%81%97%e3%81%9f/"
    },
    "headline": "これまでHexoを使ってブログを書いていましたが、毎回コマンドラインからビルドしないといけないのと、ブログ更新の間隔が空いた期間にnpmをアップデートしたらHexoがこけたりするようになってうんざりしたので、WordPr",
    "image": {
        "@type": "ImageObject",
        "url": "https://photos.yukiyamashina.com/stocksnap/thumbnail/HF5R7XDISD.jpg",
        "height": "960",
        "width": "720"
    },
    "datePublished": "2016-10-09T20:14:18+0900",
    "dateModified": "2016-10-09T20:14:18+0900",
    "author": {
        "@type": "Person",
        "name": "Yuki Yamashina"
    },
    "publisher": {
        "@type": "Organization",
        "name": "Yuki Yamashina",
        "logo": {
            "@type": "ImageObject",
            "url": "https://yukiyamashina.com/wp-yamashina/wp-content/themes/amplified/images/logo.png",
            "width": "220",
            "height": "169"
        }
    },
    "description": "これまでHexoを使ってブログを書いていましたが、毎回コマンドラインからビルドしないといけないのと、ブログ更新の間隔が空いた期間にnpmをアップデートしたらHexoがこけたりするようになってうんざりしたので、WordPressへと移行しました。使用するテーマは一からAMP HTMLで書いています。WordPressではAMP対応するプラグインがありますが、そちらではAMP用のページを別途吐き出すようになっているだけで、AMP自体の機能を色々使ったりという感じにはなっていません。自作テーマではAMPページしかないので、ちょっとしたことでもAMPコンポーネントを使っていたりします。そのうちちゃんと整理してリリースできるようにしたいです。ということで以下、雑記です。"
}
</script>

一番最初のブロックがPerson(ブログ執筆者に関するもの)、次がパンくず、最後が投稿記事に関する構造化データになっています。

PHPがおそらく必須になる

基本的にJava Scriptは禁止されています。なのでHTMLだけでjsonファイルから読み込んで何かを表示させたい、とかの場面ではamp-listとamp-mustacheを使うくらいしかできません。ただこれも、表示させるアイテムに対して条件付きで表示させるというようなことはできません。そういうことをやろうと思うとPHPを使うことになります。PHPであれば、レスポンスとして返すHTML自体がAMPになっていればいいので、今までAJAXでやってきたようなことなんかはPHP側でやることになるんじゃないかと思います。

シンタックスハイライトにはprism.jsやhighlight.jsが使えない

原則Java Scriptが禁止なので、prism.jsやhightlight.js等を利用したシンタックスハイライトは使えません。WordPressにはGeSHiをプラグイン化したWP-GeSHi-Highlightがあるので、自作テーマではこれを使用しています。ただし、WP-GeSHi-Highlightのデフォルト設定だとhead要素に言語ごとのスタイルをインラインで埋め込みますが、AMP HTMLではstyle要素にamp-customという属性をもたせる必要があるため、プラグイン内でスタイルを吐き出している部分を修正して、テーマのスタイルを吐き出す部分に移しています。

Markdownで記事を書きたいのでjetpack-markdownをカスタマイズ

WP-GeSHi-Highlightに合わせるようにjetpack-markdownもカスタマイズしています。具体的にはjetpack-markdownの中のmarkdown/lib/extra.php内の_doFencedCodeBlocks_callback関数で、デフォルトではフェンス・コードブロックに続く文字列をclass名にしている部分をlang属性の値に、さらに最終的なHTMLコードでcode要素とpre要素を入れ替えるようにしています。これで

```php
$classname =&amp; $matches[2];
$attrs     =&amp; $matches[3];
$codeblock = $matches[4];
...

のように書くとPHPとしてシンタックスハイライトしてくれます。

コンポーネントは結構増えてきている

去年2015年の年末にAMPに関するニュースが流れたときに比べて、AMPコンポーネントはかなり増えています。今ではSNSボタンもAMPコンポーネントとして用意してあったり、experimentalではあるもののform関連も使えるようになっています。その他、スマホで活躍するamp-sidebar(サイドメニュー)や、画像ギャラリーに使えるamp-carousel・amp-lightbox、Google map等の埋め込みに使うamp-iframe, 広告を表示するamp-ad・amp-sticky-ad等々いろいろあります。今後もコンポーネントは増えていくと考えられるので、jQueryのプラグインとかを使ってページを制作していた人は今のうちに勉強しておくと、一般的なwebページを制作するのに必要なものは揃っていることが分かると思います。

用意されているコンポーネントで何か面白いことができるかもしれない

面白いところでは、amp-live-listというコンポーネントで(ほぼ)リアルタイムでページを更新することが可能になっています。これを使うと簡易的なチャットページを作ることもできます。実際に試作したのがこれです。ページに飛んでもらうと、AMPで用意されているコンポーネントを使った2ch的なページを試してもらえると思います。ブラウザを2つ開いて、片方でコメントを投稿すると、しばらくしてもう一つのブラウザでもそのコメントが反映されます。ページではAMPエラーが出ていますが、一つは無料レンタルサーバで自動的に挿入されてしまうscript要素によるものと、formのPOST先を”/”で始まる相対パスで書いているのが原因ですが、SSLを入れたサーバでhttps通信ができる環境であればこのエラーは無くなります。

あと一年は遊べそう

いつまでGoogleがAMPを押していくのかは分かりませんが、あと一年くらいはAMPで色々遊べるんじゃないかと思っています。今のところはAMPで作成したページの読み込みには満足していますし、画像が自動的にlazyloadされたり、サイドメニューやカルーセルを作るのにスクラッチでJava Scriptを書いたりjQueryのプラグインを探したりなんていうことをせずに済むようになったのは大きいです。amp-live-listのように使い方によっては面白いものができそうなものもあるので、プラグインを入れて終わりではなくて、AMPに直接触れてみるのもいいんじゃないかと思います。