オリジナルブロックを作る
ブロックエディターに、独自のブロック(オリジナルブロック)を追加します。
実験的機能
この機能は Ver. 3.2 の間は実験的機能として提供し、Ver. 3.3 で正式に提供する予定です。
- 変わりうる範囲: 登録 API の名前と引数、ブロック定義に指定できる項目は、マイナーバージョンアップで変更される可能性があります。
- 変わらない範囲: PHP 側のフック処理(HTML のサニタイズの拡張など)は、この実験的機能の対象外です。従来どおりの仕様として提供しています。
- 公開 API の線引き: このページに掲載している登録 API とブロック定義の項目を公開 API として扱います。掲載外のものも利用できますが、告知なく変更されることがあります。
- サポート対象外: 管理画面に追加した独自の JavaScript・CSS は、バージョンアップ後の動作を保証しません。これらを原因とする不具合は、サポートの対象外です。
全体像
オリジナルブロックは2つの部分でできています。
| 部分 | 何をするか | 必要な場合 |
|---|---|---|
| ブロックの定義 | メニューに出すラベル・アイコンと、挿入したときの動作を決める | ほぼ必ず必要 |
| 要素の定義(スキーマ) | エディターが扱える新しい要素そのものを追加する | 既存の要素の組み合わせでは表現できない場合 |
ブロックメニューに表示するかどうかは、管理者が編集設定で選びます。 プラグイン側は「使える種類を提供する」までを行い、メニューへの表示は設定に任せる形です。
ブロックの定義と要素の定義を登録する
次の例は、注意書きを目立たせる「コールアウト」ブロックを追加します。ブロックの定義と要素の定義は、どちらも setup(ctx) の中で登録します。
ACMS.adminReady(() => {
ACMS.plugins.register('acme-blocks', {
setup(ctx) {
// 要素の定義: エディターが扱える「callout」要素を追加する
ctx.blockEditor.registerExtension('callout', ({ core }) =>
core.Node.create({
name: 'callout',
group: 'block',
content: 'paragraph+',
parseHTML: () => [{ tag: 'div[data-callout]' }],
renderHTML: () => ['div', { 'data-callout': '' }, 0],
})
);
// ブロックの定義: メニューに出すラベルと、挿入したときの動作
ctx.blockEditor.registerBlockDefinition('callout', () => ({
label: 'コールアウト',
description: '注意書きを目立たせるブロック',
icon: 'info',
isTextMenu: false,
aliases: ['callout', 'note'],
createActions: (cmd, actionCtx) => ({
action: (editor) => {
actionCtx.recordUsage(cmd);
editor
.chain()
.focus()
.insertContent({ type: 'callout', content: [{ type: 'paragraph' }] })
.run();
},
convert: () => {},
isDisabled: (editor) => editor.isActive('callout'),
isActive: (editor) => editor.isActive('callout'),
}),
}));
},
});
});ブロックの定義に指定できる項目は次のとおりです。
| 項目 | 説明 |
|---|---|
label | メニューに表示する名前 |
description | メニューの説明文 |
icon | アイコン名(Material Symbols の名前) |
isTextMenu | 選択したテキストに対する変換メニューに出すかどうか |
aliases | メニュー検索で引っかかるキーワード |
menuCategory | 編集設定の選択肢での分類(省略すると「プラグイン」の分類にまとめられます) |
createActions | 挿入・変換・状態判定の処理を返す関数 |
createActions が返すもの:
| 関数 | 呼ばれるとき |
|---|---|
action(editor) | メニューから選ばれたとき(ブロックを挿入する) |
convert(editor, pos) | 既存のブロックをこの種類に変換するとき |
isDisabled(editor, pos) | 変換先として選べないかどうかの判定。true を返すと選べません |
isActive(editor) | 現在のカーソル位置がこのブロックかどうかの判定 |
上の例のように、他のブロックからの変換に対応しない場合は、convert を何もしない関数にします。
既存のブロック(段落・見出し・画像など)の組み合わせで表現できる場合は、要素の定義(registerExtension)は不要で、ブロックの定義(registerBlockDefinition)だけで足ります。
ブロックエディターは Tiptap をベースにしています。要素の定義方法は Tiptap のドキュメントを参照してください。
Tiptap を自分で読み込まないでください
registerBlockDefinition / registerExtension に渡す関数は、引数として Tiptap を受け取ります。上の例の ({ core }) がそれです。この引数を使ってください。
プラグイン側で @tiptap/core などを import して使うと、ブロックエディター本体とは別の Tiptap が読み込まれ、エディターが正しく動作しません。TypeScript の型として参照する場合(import type)は問題ありません。詳細は 開発環境と型定義 を参照してください。
ブロックメニューに表示する
登録しただけではメニューに出ません。管理画面で表示する設定を行います。
- 管理画面の「編集設定」→「ブロックエディター設定」→「ブロックメニュー」を開きます。編集画面セットを使っているサイトでは、使っているセットの「ブロックエディター設定」を開きます(使っていないセットに保存しても、メニューには出ません)。
- 「追加」で行を増やし、「ブロック」の選択肢から、登録したブロックを選びます。選択肢には**「プラグイン」の分類**が追加されており、ブロックの定義の
label(例: 「コールアウト」)で表示されます。 - 保存します。
PHP 側の追加実装は必要ありません。 選択肢は、登録されているブロックの種類から自動的に作られます。
保存した HTML からタグが消える場合
ブロックが出力する HTML は、保存時や表示時に、不正な HTML を防ぐための仕組み(HTML のサニタイズ)を通ります。多くの標準の HTML 要素と、Ver. 3.2.36 以降では data- で始まる属性が、そのまま通ります。上の例の <div data-callout> も、Ver. 3.2.36 以降では設定なしで保存されます。Ver. 3.2.35 以前では、data- 属性も次の Hook で許可が必要です($def->addAttribute('div', 'data-callout', 'CDATA');)。
独自の要素名(例: <acme-note>)や、標準にない属性を出力する場合は、取り除かれないように PHP 側で許可します。extension/acms/Hook.php に、次のメソッドを追加してください。
public function extendsHtmlPurifierDefinition(\HTMLPurifier_HTMLDefinition $def, \HTMLPurifier_Config $config): void
{
$def->addElement('acme-note', 'Block', 'Flow', 'Common');
}許可する要素・属性の定義はキャッシュされます。変更したあとは、ダッシュボードからキャッシュをクリアしてください。詳細は フック処理 を参照してください。
関連ページ
- ブロックエディターの基本 — ブロックエディター自体の使い方
- 機能の登録(レジストリ)
- 開発環境と型定義 — TypeScript で書く場合
変更履歴
| バージョン | 変更内容 |
|---|---|
| Ver. 3.2 | 新規追加(実験的機能) |