WordPressから静的HTMLを生成するプラグインを調べた

# はじめに
WordPressはページにアクセスするとPHPが動作してDBからデータをとってきて
ページを都度都度作成してくれます。
そんなWordPressで作成したページでも、静的ページにしたいというときがありますよね。

もう少し具体的にいうと…
AWSにEC2とS3を用意して、EC2にWordPress、S3に記事のHTMLを置いて、S3を公開したいというときがありますね。
ありますよね？

今回はそんな時にWordPressで使用するWordPressのページを静的HTMLにしてくれるプラグインについて書きます。
同時に実際に使用したプラグインWP2Staticの感想も添えてみます。

# メリットデメリット
このWordPressの静的HTMLを生成してS3で公開することのメリットデメリットを考えてみました。
###メリット
- HTMLなので、読み込みが速い（PHPを挟んでいない）
- S3にWordPressを設置しない（できない）ので、WordPress経由での攻撃が無くなる

### デメリット
- リアルタイムでのデータが表示されるわけではないので、アクセスごとにデータを変更するようなページには不向き
- 予約投稿はできない（と思ったほうが良い）

# プラグイン
ただ、WordPress自体が静的HTMLを自動で生成してくれるわけではないので、ここではプラグインを使用して静的HTMLを生成する必要があります。
この「静的HTMLを生成する」ということ自体、あまり需要がないからかもしれないのですが、プラグインの数はけっこう限られてきます。
「wordpress static html plugin」というような検索ワードでプラグインを探してみたのですが、そんなに数は見つからず…。
実際に導入を検討したプラグインは以下の3つです。

- StaticPress http://ja.staticpress.net/
- Simply Static https://www.simplystatic.co/
- WP2Static (旧：WP Static HTML Output) https://wp2static.com/

# 静的HTML生成の流れ
どのプラグインでも静的HTML作成には以下のような動作を取ります。
1. 取得対象となるページのリストを作成（DBから記事の登録状況をみて生成）
2. 1で作成したリストに沿って、プラグインがページをGETで取得
3. HTMLの内容を精査
4. 3で精査した内容をもとにページ内の画像やファイルを取得
5. サーバ内のローカルフォルダにHTMLとしてページを保存
6. （オプション）5の内容をS3に送る

6の動作はプラグインによっては搭載されていないこともあります。
搭載されてない場合はスクリプトを自分で書くなどの工夫を強いられますね。

# プラグイン共通の悩み
使用して調べていくうちにどのプラグインでも当たってしまった悩みを最初に書きます。

- 自分自身がサーバにアクセスできるように設定しないとクロールされない（IP制限しているサーバは注意）
- ページ全部を自動でクロールしてくれるわけではない（DBに登録されているデータを元にページリストを自動生成するので、ゴリゴリカスタマイズしている場合は、プラグインの初期設定だと意図したとおりにクロールしてくれない。私はrewrite_ruleでアドレスを操作していたので尚更躓きました。このあたりは設計の段階でしっかりしていればあまり心配ないのかもしれませんね。（反省））
- ページ数が多くなればなるほど生成に時間がかかる
　サーバスペックに依存するところもあるが、やはりページ数が多いと時間もかかる。
　同じページ数ならMTの再構築のほうが速度的には速い。なんでかは知らない。
　ページ内で使用されている画像も生成対象として含まれるので、記事内に画像が多く入っている場合はさらに時間がかかる
- 標準設定でできないことをやろうとするとカスタマイズに時間がかかる（WordPressあるある）
- 日本語URL/ファイル名には対応していない。

# プラグインの特徴（主観有り）
### StaticPress
- プラグインの最終更新日は4年前…。
- ドキュメントにしっかりした日本語があるため、導入までの手順がわかりやすい。
- 設定項目を増やすことができるアクションフックが用意されている。
- …しかし、HTML生成対象になるURLを変えようと思ったらコアファイルをカスタマイズする必要あり。（そのためのアクションフックは存在しない）
- HTML生成対象になるURLのリストはDBに独自のテーブルを作って保存している。
- StaticPressはS3アップ用にスクリプトを公開している。S3に転送する場合はこのスクリプトを追加すると良い。
 http://ja.staticpress.net/2013/06/11/69/
- 3つのプラグインの中ではStaticPressの使用率が高い（ような気がします。特に日本では…。母数が少ないのでなんともですが）

### Simply Static
- プラグインの最終更新日は2年前…。
- このプラグインが使用できるかというサーバ設定を診断してくれる。（この機能だけ使って自身がクロールできるかを調べた）
- PHP7以降だとワーニングが多発してしまう。（ PHP Warning:  preg_match(): Compilation failed: invalid range in character class at offset ** PHP7.3から発生なので、PHP7.2だと動くのかもしれない…そこは試してない）
- 配送先として選べるのはサーバ内ディレクトリかZIPアーカイブなので、S3などにアップする場合は自分でやらないといけないっぽい
- HTML生成対象になるURLのリストはDBに独自のテーブルを作って保存している。

### WP2Static
- プラグインの最終更新日は3週間前。比較的更新してくれている。最近のバージョンでも動作検証されている。
- 配送先をS3などにするというのは次のバージョンで有料化される（バージョン7からの予定）。現在のところは無料。
- ドキュメントは英語のみ。
- フィルター/フックがけっこう存在するので、一番カスタマイズが楽だった
- HTML生成対象になるURLのリストははプラグインフォルダに管理表を生成して管理している
- クロール前にHTML生成対象のファイル一覧をみることができる
- 日付アーカイブには対応していないので、自分でクロール対象として追加する必要がある

# プラグインを使ったときの難所について
特に「ページ全部を自動でクロールしてくれるわけではない」というところは難所でした。
ここは私が最初の設計段階でちょっと失敗しているというのもあるとは思うのですが…。
失敗しているとしても…どのプラグインでも全部を思った通りにやりたい、と思うならある程度のカスタマイズは必要になってきます。
とはいえ、プラグインもカスタマイズ前提で作られているわけではないので、難しいところです。
プラグインの数が少ないということは需要も少ない、需要が少ないということは実際にカスタマイズして使っている人はもっと少ない、ということはカスタマイズに必要な情報を仕入れてくるのは大変ということになります。
…という苦労を重ねたので、カスタマイズのやりやすさなどを踏まえてそれぞれのプラグインの特徴を**主観を入れて**書いてみました。

# 実際に使用したのはWP2Static
私はゴリゴリにカスタム投稿やカスタムタクソノミーを追加してバリバリURLはリライトさせていたので、標準設定だとクロールしてくれないページが多かったです。
そのため、クロール対象を追加/削除ができるプラグインを探していました。
3つの中ではWP2Staticのみ専用のアクションフックがあったので、WP2Staticを採用しました。
他の2つのプラグインでは専用のフックがなくて、クロール対象のURLを追加/削除するためにはどうしてもプラグイン本体のコードを書き替えなくてはいけないようだったのです。
あまりカスタマイズをしていない、もしくはカスタマイズはしているが細かいところも一致するようだったら他の2つのプラグインでも良いのかと思います。
（ただ、Simply StaticはPHP7.3以降では動作は危うい）
静的HTMLに変換する速度的にはどのプラグインでも変わらないかな…という気がします。ページ数やサーバのスペックにもよるのですが、ページ数が増えれば増えるほど時間はかかります。

# おわりに
作成したHTMLを見ると、やはり表示速度が違いますね。速いです。
ですが、HTMLを生成するにはそれなりに時間がかかるので、更新の気軽さは落ちるのかも知れません。
今回しらべたのは代表的なプラグインのみですが、他に良いプラグインがあれば教えてください。

# 余談
[un-T factory! XA Advent Calendar 2019](https://qiita.com/advent-calendar/2019/unt-xa)の7日目として書いています。
すみません、私はフロントエンドエンジニアではないのですが、ひっそりと参加しました。