(-> % read write unlearn)

My writings on this area are my own delusion

Netlify CMS のマークダウンエディタの日本語入力がバグってるので雑に対応する

先に結論まとめ

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 やプレビュー機能を持つ Widgetmarkdown Widget

markdown` Widget の日本語入力のバグとは

以下の Issues はたぶん全部同じ事象。各 Issue に動画や Gif が貼られているので見ると挙動はよく分かる。

原因

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 タグが使われるので、

  1. マークダウンを書くためのサポートや WISWIG 機能がなくなる。
  2. マークダウンをレンダリングしたプレビューがされない。

妥協案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 Widgetsanitize_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 をキャッチアップしたい。