雑記ブログ:技術選定4「WPcomの活用」
Closedfirst published: 2019/01/02last updated: 2019/01/15
技術選定3の続き。うーん、高機能なheadlessCMSほど依存性が高い...。
生存競争の激しいheadlessCMS同士のインポート・エクスポート問題はそう簡単に解決しないだろうし、仮にJSONで吐き出せても上手く変換して移行先に移せる自信はないよ。
そういえば、prismicのSlice機能を使っててWordPressのGutenbergを思い出した。あれって、Gatsbyに引っ張ったらどうなるんだ?さすがにメジャーリリースされた機能を無視してはいないだろう。
サーバーレスにしたいので、WPcom(Free Plan)でテスト。
プラグインの追加はビジネスプラン以降だけど、Jetpack(基本機能)はプリインストールされているので、そのままGutenberg用のMarkdownブロックが使える。ブロックには個別にクラス名を付与したりもできる。
このデータをGatsbyで引っ張ってみる。
おお!?MarkdownがHTMLに変換されている!Remarkは通してないので、GraphQLで引っ張った時点でHTMLになっているのか。
Gutenbergで組んだ部分は wp-block-*
のclassが生きてる。ということは、このブログのように1つの投稿内で型を再利用(リピーターフィールド的な)しているような構成も作れる気がする。
※クラシックエディタで書いた部分はプレーンなHTMLに変化
画像は figure
でラッピングされ、iframeは内容に応じた div
で階層化。コードを書く pre
だけ、専用ブロックだと一番外が pre
となりこのブログでは都合が悪かった。Markdownブロックで書くことで解決。
open / closeはカテゴリーを見て出し分け、アイコンはタグの1つ目を見て出力、updateAtはmodifiedが同じだし、ほとんどのものは再現できた。
難関は画像タグをReactコンポーネントに置換していた部分。次のようなデータ構成になってほしいが↓
全部入り1フィールドになるので悩ましい↓
これだと、rehype-reactの置換ができない。かといって、1度Markdownに戻してしまったら wp-block-*
のclassがなくなってしまうし。実は同じ問題で、Prismjsが使えないという話も。
custom normalizerが使える?いや、これは定義できていないものをなんとかするやつかな?効果は見出せなかった。
Issueを辿っていっているうちに、gatsby-mdxという野心的なGatsbyプロジェクトを見つけた。MDXというのは、MarkdownとReactコンポーネントを混ぜたようなやつ。VuePressがVueで似たことしてたの思い出した。
使ってみたものの、うまくWordPressソースを引っ張れず(GraphQLに出てこない出ない)、設定も「前は必要だったが今は自動」とか書かれててよくわからん。ドキュメントは見直し中とのこと。
ここまでの手法は使えそうにない。もっと単純な置換でなんとかならんものか。content
をJSONにすればいける?
html2jsonではうまく情報が渡せなかった。JSONになってればいいとかではないらしい。確かに他のパラメータないし。これは、ちゃんと構文木とやらにしないとダメだな。
というわけで、unifiedとrehype-parseを組み合わせたら content
を構文木情報にできて、画像のReactコンポーネント差し替えは成功!unified関連のプラグインが無数にあってかなり迷った...。
const unified = require("unified")
const rehypeParse = require("rehype-parse")
const renderAst = new rehypeReact({
createElement: React.createElement,
components: {
img: ZoomImage
}
}).Compiler
{(() => {
const tree = unified()
.use(rehypeParse, { fragment: true })
.parse(data.wordpressPost.content)
return renderAst(tree)
})()}
シンタックスハイライトに関しては、色々試してみてreact-prismとprismjsの組み合わせでうまくいった。iframeはアスペクト比がclass名で出力されていたのでCSSで対応。
最後に、excerpt
で引っ張ったデータに不要なpタグが入ってる問題があったのでプレーンテキストに変換。rehype-remarkでもいいけど、ここは完全に無駄なタグをぬけるようhtml2plaintext v2.1.0を使用(v2.1.2はパーサーがみつからないエラー)。
似た用途に見えたhtml-to-textはサーバー無いと動かないライブラリだったらしく今回のプロジェクトには組み込めなかった。
Reactコンポーネントへの差し替えで時間を食ったけど、headlessCMSのリピーターフィールドで作っていたスレッド型式や、その他もろもろの機能をWPcomだけで再現しつつ、全記事移行できた。
あとは、Netlifyのビルド対象リポジトリを切り替えて完了ー!...と思いきや、デプロイエラーが発生。
error GraphQL Error Field "jetpack_featured_media_url" of type "wordpress__wp_media" must have a selection of subfields. Did you mean "jetpack_featured_media_url { ... }"?
「メディアタイプにはサブフィールド必須でしょ」と言われているけど、jetpack_featured_media_url
にサブフィールドはなく、Jetpackが入っているからか featured_media
がGraphQLで出ない。
Jetpackを切るとMarkdownブロックが効かなくなるほか、マルチサイト管理機能も失われるなど色々と面倒が多い。極力切りたくない。
ローカルではdevelopでもbuildでも通るのになぜ...。二進も三進もいかないのでIsuueでお願いしておいた。なので、現状はアイキャッチ画像がOG画像として設定できない。直ってほしいところ。
Jetpack有効化時のアイキャッチ問題は残ったけど、その他は実用レベルにあると思う。Gutenbergはクラシックエディタより断然書きやすい。容量やACF Proが必要でプランUPしてもMAX25ドル/月。リクエスト数の明記なし。
何より、headlessCMSで不安だった生存率が高い。バックアップやエクポートで他のWordPress環境に逃しやすいので安心。また、WebHooksも使えるようなので、クライアントに更新させてデプロイなどもできそう。
というわけで、しばらくはWPcomを使っていこうかと。あとは別の用途でAirtableも安定してきているのでそちらも。