【第6回】Tiptap 拡張とカスタムボタンで独自機能を追加 - MTAppjQuery で Movable Type 9 のリッチテキストエディタをカスタマイズ

2026-08-24
12分で読了
更新: 2026-08-24
mtappjquery-customize-rte.webp

目次

この記事は「MTAppjQuery で Movable Type 9 のリッチテキストエディタをカスタマイズ」の第6回です。今回は、エディタに独自の機能を追加する2つの方法をご紹介します。Tiptap 拡張の自作と、ツールバーへのカスタムボタンの追加です。

コードを書き込む場所(自由テキストエリア)とベースコードについては第1回をご覧ください。

Tiptap の API を使えるようにする

第5回でお伝えしたとおり、MTRichTextEditor の土台は Tiptap というエディタフレームワークです。そして MTRichTextEditor は、Tiptap のコア API を取り出すための入口を公式に用意してくれています。

MTRichTextEditor.import('@tiptap/core').then(({ Extension, InputRule }) => {
    // ここで Tiptap の API が使える
});

MTRichTextEditor.import('@tiptap/core') は Promise を返し、Tiptap の ExtensionInputRule といったクラスにアクセスできるようになります。npm でパッケージを入れたりビルド環境を用意したりする必要はありません。自由テキストエリアに書くコードだけで完結します。

なお、import に指定できるモジュール名は @tiptap/core です。それ以外の名前を渡すとエラーになります。

入力パターンで自動変換する拡張を作る

公式の開発者向けガイドに載っている、分かりやすい例から始めましょう。:+1: と入力すると絵文字の 👍 に自動変換される拡張です。

:+1: と入力すると 👍 に自動変換される動作
<script type="module">
if (window.MTRichTextEditor) {
    MTRichTextEditor.import('@tiptap/core').then(({ Extension, InputRule }) => {
        const thumbsUpExtension = Extension.create({
            name: 'thumbsUp',
            addInputRules() {
                return [
                    new InputRule({
                        find: /:\+1:/,
                        handler: ({ state, range }) => {
                            state.tr.insertText('👍', range.from, range.to);
                        },
                    }),
                ];
            },
        });

        MTRichTextEditor.on('create', (options) => {
            options.extensions.push(thumbsUpExtension);
        });
    });
}
</script>

流れを整理すると次のとおりです。

  1. MTRichTextEditor.import('@tiptap/core')ExtensionInputRule を取り出す
  2. Extension.create() で拡張を定義する。addInputRules() は「この正規表現にマッチしたらこう処理する」という入力ルールを返す
  3. create イベントで options.extensions に追加する

InputRule は Markdown 記法の自動変換と同じ仕組みなので、応用範囲は広いです。社内でよく使う記号の変換、定型文の展開など、入力の手数を減らすカスタマイズに向いています。

ツールバーにカスタムボタンを追加する

もうひとつの方法が、ツールバーへの独自ボタンの追加です。MTRichTextEditor のツールバーボタンは Web Components(カスタム要素)として実装されていて、自分でカスタム要素を定義して登録できます。

要素名は mt-rich-text-editor-toolbar-item- に続けてボタン名を付けるという命名規則です。ベースクラスの ToolbarItemElementMTRichTextEditor.Component から取り出します。

定型の挨拶文を挿入するボタンの例です。

カスタムボタンから定型の挨拶文が挿入される動作
<script type="module">
if (window.MTRichTextEditor) {
    const { ToolbarItemElement } = MTRichTextEditor.Component;

    // ボタン名 greeting のカスタム要素を定義
    customElements.define(
        'mt-rich-text-editor-toolbar-item-greeting',
        class extends ToolbarItemElement {
            constructor() {
                super();

                const button = document.createElement('button');
                button.title = '定型の挨拶文を挿入';
                button.innerHTML =
                    '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24">' +
                    '<path fill="currentColor" d="M3 4h18v13H8l-5 4V4zm3 4v2h12V8H6zm0 4v2h8v-2H6z"></path>' +
                    '</svg>';
                button.addEventListener('click', () => {
                    this.tiptap?.commands.insertContent(
                        '<p>いつもお読みいただきありがとうございます。</p>'
                    );
                });

                // ボタンは shadowRoot に追加する
                this.shadowRoot.appendChild(button);
            }

            connectedCallback() {
                super.connectedCallback();
            }
        }
    );

    MTRichTextEditor.on('create', (options) => {
        // 2行目 > 左寄せエリア の末尾にボタンを追加
        const toolbar = structuredClone(options.toolbar);
        toolbar[1][0].push(['greeting']);
        options.toolbar = toolbar;
    });
}
</script>

ToolbarItemElement が用意してくれるのはボタン用のスタイルだけなので、constructor の中で <button> を作って this.shadowRoot に追加します。ここを忘れると中身のない幅 0 のボタンになり、ツールバーには何も表示されません。公式のサンプルプラグインも同じ書き方です。

クリック時の処理では this.tiptap から Tiptap のコマンド API を呼び出しています。insertContent はカーソル位置に HTML を挿入するコマンドです。あとはボタン名(ここでは greeting)を第2回で学んだ要領でツールバー配列に加えれば、ツールバーに表示されます。

ツールバーを structuredClone で複製してから書き換えているのは、第2回で触れたとおり options.toolbarcreate の呼び出しごとに同じ配列で渡ってくるためです。直接 push するとリッチテキスト欄の数だけボタンが増えてしまいます。一方で先ほどの options.extensions は呼び出しごとに別の配列が渡ってくるので、そのまま push して構いません。

ツールバーの構成は設定画面の内容によって変わるので、options.toolbar[1][0] の添字はお使いの環境に合わせて調整してください。

公式のサンプルプラグインも参考に

シックス・アパートからは、エディタ拡張の公式サンプルプラグイン集が公開されています。絵文字パレットやフォントサイズ変更など、実践的な実装例が揃っているので、ここまでの内容を理解した上で読むととても勉強になります。

サンプルは Movable Type のプラグイン形式ですが、JavaScript 部分の書き方は今回ご紹介した方法と同じです。気に入った機能があれば、JavaScript 部分を MTAppjQuery の自由テキストエリアに移植して使うこともできます。

まとめ

今回のポイントを整理しておきます。

  • MTRichTextEditor.import('@tiptap/core') で Tiptap のコア API をビルド環境なしで使える
  • Extension.create()InputRule で入力の自動変換が作れる。作った拡張は options.extensions.push() で追加する
  • カスタムボタンは MTRichTextEditor.Component.ToolbarItemElement を継承したカスタム要素として定義する。要素名は mt-rich-text-editor-toolbar-item-ボタン名で、ボタン本体は constructorshadowRoot に追加する
  • ツールバーに加えるときは options.toolbar を複製してから書き換える(options.extensionspush で構わない)
  • 公式サンプルプラグイン集が実践例の宝庫

次回は連載の最終回として、これまでのカスタマイズをサイトごと・画面ごとに出し分ける方法を取り上げます。

今回は以上となります。

この記事をシェア

関連記事