microCMSのリッチエディタ内でHTMLタグを使いたい
microCMSで文章を入稿するときのHTMLタグ問題
このブログはmicroCMSでコンテンツ管理を行っている。
通常、ブログのような執筆物を書く場合であれば、microCMSのスキーマ中に「本文」のようなリッチエディタで編集可能な要素を設け、これに記述を行っていくことになるかと思う。
ただ、リッチエディタには任意のHTMLタグを埋め込む機能がない。エディタ中に書いたタグは自動でエスケープされてしまう。
アフィリエイトの埋め込みや、microCMS側が対応していない動画サイト等の埋め込みは現状簡単にはできない。
公式としてはこちらのページに記載のように、そもそもスキーマをリッチエディタと、テキストフィールド(HTMLタグも入る)の繰り返しとしてカスタムフィールドを定義することで、HTMLタグを埋め込みしつつリッチエディタも使えるようにする方法が紹介されている。
また、任意の識別子を文章中に埋め込み、ショートコードで書き換える実装を実践されている方もいるようだ。
比較すると以下のような感じだと考える。自分としては今回はどちらもデメリットが気になるところがあり、別の手段をとることにした。
① リッチエディタとHTMLを含むカスタムフィールドを利用する
利点
- microCMSから帰ってくるHTMLを加工する必要がない
欠点
- 既に運用開始している場合、スキーマの変更が必要となるため導入コストが高い
- HTMLタグの断片が多い場合、WUI上での表示・設定が長く煩雑になる
② 識別子を埋め込んでショートコードで書き換える
利点
- 使っているリッチエディタのスキーマ変更がいらない(ショートコード関連の追加は必要)
欠点
- 毎回同じコードスニペットを埋め込むような場合には問題ないが、アフィリエイトなど、タグが毎回異なるものは毎回ショートコードを追加して管理する必要が出てくる
- ページ生成する側でショートコードのAPIを毎回叩く必要がある
HTMLタグを取得した側でアンエスケープしてやればいいじゃない
そこで、今回は単に特定条件で>と<をアンエスケープすることでHTMLタグとして動作させることにした。
お行儀としては非常によくないと思うが、
- 自分のブログはGatsby製で、Static Site Generateしている
- 書くのは自分だけ
- リッチエディタから取得してきたHTMLをGatsby(というかReact)で反映させる地点でどのみちdangerouslySetInnerHTMLでHTMLを書き換える必要がある
ことから、自分の場合は実害はないと判断。
任意のHTMLを挿入出来うるので、入稿データを信頼できない場合は絶対に行うべきではない。
利点:
- スキーマの追加・変更なしで実現できる
- microCMSへの依存が少ない(コンテンツのjsonさえ持ってきて同じように置換すればよいので、最悪microCMSから他サービスへの乗り換えをしたい、と思ったときもやりやすいはず)
欠点:
- microCMS APIから帰ってくるのはエスケープされたHTMLなのが気持ち悪い
実装
リッチエディタから取得できるHTMLのうち、意図してアンエスケープしたい部分だけを上手く抽出する必要がある。
これはやり方を悩んだが、文章中に偶然には発生しないだろう、ということで<br>2回を前後に持つ<div>タグを対象とすることにした。
Gatsbyでの実装イメージは以下の通り。おおよその構成は
microCMS公式のgatsby+microCMS構成を参照。ブログページのjsのdata.microcmsBlog.bodyを書き換える。
//microcmsBlogはgraphqlで取ってきている想定
const b = data.microcmsBlog;
//<br>の繰り返しに囲まれた<div>内部の<および>を置換する
const body = b.body.replace(new RegExp("<br><br><div.*?/div><br><br>", "g"), (tmpStr)=>tmpStr.replace(/<br>/g,"").replace(/</g, "<").replace(/>/g, ">"))
へっぽこ正規表現力を晒してしまった。他にもアンエスケープしなければいけないものはたぶんあるけど出てきてから考える。