先に結論まとめ
public/admin/index.html
<script src="https://unpkg.com/netlify-cms@^2.0.0/dist/netlify-cms.js"></script> <!-- 以下を追加 --> <script> const schema = { properties: { sanitize_preview: { type: 'boolean' } } } CMS.registerWidget('md', CMS.getWidget("text").control, CMS.getWidget("markdown").preview, schema); </script>
Netlify とは
静的サイトホスティングの SaaS/PaaS 。サービス名であり会社名。 Vercel や Firebase (Firebase Hosting) などと近い。
Netlify CMSとは
Netlify 社がメインでメンテする OSS の Headless CMS 。 Headless CMS のなかでも Git Based というタイプで、その他の大多数の API Based の Headless CMS と違い Database (RDB) を必要としないのが特徴。だけど、機能は豊富で拡張性も高い。
markdown
Widget とは
Netlify CMS の執筆編集画面の各フォームは Widget
というコンポーネントになっており、日付入力フォーム、ファイルアップロードフォーム、など多数の Widget がビルトインで存在する。マークダウンの WISWIG やプレビュー機能を持つ Widget が markdown
Widget 。
markdown` Widget の日本語入力のバグとは
以下の Issues はたぶん全部同じ事象。各 Issue に動画や Gif が貼られているので見ると挙動はよく分かる。
- Jumping input cursor to end of text in markdown widget · Issue #6580 · netlify/netlify-cms
- Jumping input cursor to end of text in markdown widget · Issue #6580 · netlify/netlify-cms
- markdown editor is buggy on Google Chrome · Issue #6553 · netlify/netlify-cms
- Japanese IME bug when entering image alts and titles in rich text editing mode · Issue #4629 · netlify/netlify-cms
原因
markdown
Widget が内部で使っている Slate Editor の問題、あるいはSlate Editor との連携の問題のよう。
根本解決
使っている Slate Editor を最新に置き換える。そういった議論も存在する。
ただし、Issue 内では次のようにコメントされているので、中の人が積極的に修正に動く気配は今のところなさそう。
Hi @acomagu updating to the latest version of slate is not a simple task. See https://docs.slatejs.org/concepts/xx-migrating. We're open to a contribution for the upgrade if anyone if up to the challenge
妥協
妥協案1
markdown
Widget ではなく text
Widget を使う。この場合、単なる textarea
タグが使われるので、
- マークダウンを書くためのサポートや WISWIG 機能がなくなる。
- マークダウンをレンダリングしたプレビューがされない。
妥協案2
markdown
Widget のプレビュー機能と text
Widget のインプットフォーム機能を組み合わせた Custom Widget を使う。この場合、妥協案1の1つ目の課題は解決しないが、2つ目の課題は解決する。
- [ ] マークダウンを書くためのサポートや WISWIG 機能がなくなる。
- [x]
マークダウンをレンダリングしたプレビューがされない。
方法
public/admin/index.html
<script src="https://unpkg.com/netlify-cms@^2.0.0/dist/netlify-cms.js"></script> <!-- この直下に custom widget を登録する処理を3行で追加 --> <script> CMS.registerWidget('md', CMS.getWidget("text").control, CMS.getWidget("markdown").preview, {}); </script>
説明
widget をカスタムで自前開発する場合、パーツとしては入力欄機能とプレビュー機能をそれぞれ HTML (というか React Component) として作成する。そのため、入力機能は text widget から、プレビュー機能は markdown widget から、それぞれ拝借するということが簡単にできる。できた。上記のコードでは md
という名前で Widget を登録しているので config.yaml では以下のように参照し使用する。
- { label: 本文), name: body, widget: md }
補足
markdown Widget の sanitize_preview
オプションを解釈させたいなら次のように。
<script src="https://unpkg.com/netlify-cms@^2.0.0/dist/netlify-cms.js"></script> <script> const schema = { properties: { sanitize_preview: { type: 'boolean' } } } CMS.registerWidget('md', CMS.getWidget("text").control, CMS.getWidget("markdown").preview, schema); </script>
各ビルトイン Widget の実装
ここにある。モノリポ構成。
自前で作るなら上記のコードを参考にしつつドキュメンを参照。
感想
1年前はこんなバグなかった気がする。残念。時間ができたら Slate Editor をキャッチアップしたい。