2026年5月27日
2026年5月27日
WordPressのブロックエディターにカスタムTransformを実装してブロック変換を追加する
ブロックの「変換」メニューに独自の変換先を増やすには、ブロック登録時の transforms プロパティに from(他のブロックから自分へ)と to(自分から他のブロックへ)を定義します。コアブロックに変換を足したい場合は、JavaScript の blocks.registerBlockType フィルターで設定を書き足します。この記事では、注意書きボックスの独自ブロックを例に、段落からの変換、複数ブロックをまとめる変換、入力の先頭文字で変換するプレフィックス変換、そして引用ブロックへの変換追加までを順に実装します。
Transform の基本:from と to、type の種類
ブロック変換は、ブロックを選択してツールバー左端のブロックアイコンを押したときに出る変換先の一覧を支えている仕組みです。段落を見出しに、引用をプルクオートに、といった操作はすべてこの transforms 定義から生まれています。
定義は from と to の二方向に分かれます。自作ブロックであれば、他のブロックから自分への変換を from に、自分から他のブロックへの変換を to に書きます。どちらか片方だけでも動きます。
各変換には type を指定します。よく使うのは次の種類です。
block:既存のブロックを選択して変換メニューから切り替える、もっとも一般的な変換prefix:段落の先頭で特定の文字を入力しスペースを押したときに変換する(-でリストになるのと同じ仕組み)enter:段落に特定の文字列だけを入力して Enter を押したときに変換するraw:外部からHTMLが貼り付けられたときに、そのHTMLを解析して変換するfiles:ファイルがドロップされたときに変換するshortcode:ショートコードを貼り付けたときに変換する
transforms は block.json には書けず、JavaScript 側の registerBlockType の設定として渡します。関数を含むため JSON では表現できないからです。
準備:変換先になる注意書きブロック
例として、段落を中に入れられる注意書きブロック my-plugin/notice を用意します。中身を InnerBlocks にしておくと、段落を複数入れたり、元の段落にそのまま戻したりする変換が素直に書けます。
npx @wordpress/create-block でひな形を作ると、block.json、src/index.js、ビルド設定がそろいます。作業はステージング環境かローカル環境で行い、既存の投稿に適用する前にバックアップを取ってください。
block.json の要点は次のとおりです。
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 3,
"name": "my-plugin/notice",
"title": "注意書き",
"category": "text",
"icon": "warning",
"textdomain": "my-plugin",
"editorScript": "file:./index.js",
"style": "file:./style-index.css"
}
PHP 側は init で register_block_type() にビルド後のディレクトリを渡します。
add_action( 'init', function () {
register_block_type( __DIR__ . '/build' );
} );
段落からの変換(type: block)を実装する
src/index.js で、edit / save とあわせて transforms を定義します。
import { registerBlockType, createBlock } from '@wordpress/blocks';
import { useBlockProps, InnerBlocks } from '@wordpress/block-editor';
import metadata from './block.json';
const ALLOWED = [ 'core/paragraph', 'core/list' ];
registerBlockType( metadata.name, {
edit() {
return (
<div { ...useBlockProps( { className: 'my-notice' } ) }>
<InnerBlocks allowedBlocks={ ALLOWED } template={ [ [ 'core/paragraph' ] ] } />
</div>
);
},
save() {
return (
<div { ...useBlockProps.save( { className: 'my-notice' } ) }>
<InnerBlocks.Content />
</div>
);
},
transforms: {
from: [
{
// 段落 1 つでも、複数選択でも変換できるようにする
type: 'block',
blocks: [ 'core/paragraph' ],
isMultiBlock: true,
transform: ( attributesList ) =>
createBlock(
'my-plugin/notice',
{},
attributesList.map( ( attributes ) =>
createBlock( 'core/paragraph', attributes )
)
),
},
{
// 段落の先頭で「!!」と入力してスペースを押すと変換
type: 'prefix',
prefix: '!!',
transform: ( content ) =>
createBlock( 'my-plugin/notice', {}, [
createBlock( 'core/paragraph', { content } ),
] ),
},
],
to: [
{
// 注意書きを解除して、中身の段落だけを残す
type: 'block',
blocks: [ 'core/paragraph' ],
transform: ( attributes, innerBlocks ) => innerBlocks,
},
],
},
} );
いくつか、なぜこう書くのかを補足します。
isMultiBlock を true にすると、引数が配列になる。 複数の段落を選択したときにも変換メニューに注意書きが出るようになり、transform には各ブロックの属性の配列が渡されます。単数選択のときも長さ 1 の配列になるため、同じ関数で両方を扱えます。
createBlock の第3引数で中身を組み立てる。 第1引数がブロック名、第2引数が属性、第3引数が内側のブロックの配列です。段落の属性をそのまま渡しているので、太字やリンクなどの書式も保たれます。
to の transform は第2引数に innerBlocks を受け取る。 内側のブロックの配列をそのまま返すと、外枠だけを外した状態になります。ブロック変換の戻り値は、1 つのブロックでもブロックの配列でもかまいません。
prefix 変換の引数は、プレフィックスを除いた残りの内容。 !! に続けて入力していた文字列が content として渡されます。プレフィックスにはほかの機能と重ならない記号を選んでください。- や 1. はリスト、> は引用にすでに使われています。
変換できる条件を絞る(isMatch)
空の段落まで変換候補に出ると、操作の邪魔になることがあります。isMatch を足すと、条件を満たすときだけ変換先として表示されます。
{
type: 'block',
blocks: [ 'core/paragraph' ],
isMultiBlock: true,
isMatch: ( attributesList ) =>
attributesList.every( ( { content } ) => String( content ?? '' ).trim() !== '' ),
transform: ( attributesList ) => { /* 前の例と同じ */ },
}
段落の content 属性は、WordPress 6.5 以降はリッチテキストを表すオブジェクトとして扱われることがあります。文字列として比べたいときは、上のように String() で変換してから扱うと、バージョンの違いに左右されにくくなります。isMultiBlock が true のときは、isMatch にも属性の配列が渡される点に注意してください。
コアブロックに変換先を追加する(blocks.registerBlockType フィルター)
自作ブロック側の from に書けば、コアの段落から注意書きへの変換は実現できます。一方、コアブロック側の変換メニューに項目を足したい場合や、自分では変更できない他プラグインのブロックに変換を足したい場合は、フィルターで登録前の設定を書き換えます。
次は、引用ブロックから注意書きブロックへの変換を引用ブロック側に追加する例です。
import { addFilter } from '@wordpress/hooks';
import { createBlock } from '@wordpress/blocks';
addFilter(
'blocks.registerBlockType',
'my-plugin/quote-to-notice',
( settings, name ) => {
if ( name !== 'core/quote' ) {
return settings;
}
const transforms = settings.transforms ?? {};
return {
...settings,
transforms: {
...transforms,
to: [
...( transforms.to ?? [] ),
{
type: 'block',
blocks: [ 'my-plugin/notice' ],
// 引用の出典(citation)はこの変換では引き継がない
transform: ( attributes, innerBlocks ) =>
createBlock( 'my-plugin/notice', {}, innerBlocks ),
},
],
},
};
}
);
このフィルターは、ブロックが登録される瞬間に適用されます。そのため、コアブロックの登録より前にこのコードが読み込まれている必要があります。上の注意書きブロックと同じ editorScript に含めるか、enqueue_block_editor_assets で読み込むスクリプトに入れておけば、通常はエディターの初期化前に実行されます。既存の変換を消さないよう、元の to 配列を展開してから追加しているのも大事な点です。
引用ブロックは内側に段落などを持つ構造になっているため、innerBlocks をそのまま注意書きに渡せます。注意書きの allowedBlocks に含まれないブロック(画像など)が引用の中にあった場合の扱いはバージョンによって異なる可能性があるので、さまざまな中身の引用で試しておくと安心です。
動作確認の方法
ビルド後に投稿編集画面を開き、次の操作で一つずつ確かめます。
- 段落を 1 つ選択し、ツールバーのブロックアイコンから変換先に「注意書き」が出るか
- 段落を複数選択して同じ操作をし、1 つの注意書きにまとまるか
- 新しい段落の先頭で
!!に続けてスペースを入力し、注意書きに変わるか - 注意書きを選択して段落に戻すと、中身の段落が残るか
- 引用ブロックの変換先に「注意書き」が増えているか
変換メニューの位置や表記はバージョンで変わることがあります(2026年10月現在)。画面で見つからないときは、開発者ツールのコンソールで登録内容を確認できます。
wp.blocks.getBlockTransforms( 'from', 'my-plugin/notice' );
wp.blocks.getBlockTransforms( 'to', 'core/quote' );
追加した変換が配列に含まれていれば、登録自体は成功しています。メニューに出ない場合は isMatch の条件や、変換先ブロックの登録状況(そのブロックが挿入可能か)を見直します。
変換後は、投稿を保存して再読み込みし、「このブロックには予期しないコンテンツが含まれています」のようなブロック検証エラーが出ないかも確認してください。save 関数を後から変更すると、変換とは無関係に検証エラーが出ることがあるため、切り分けの際は変換前後のブロックのHTMLをコードエディターで見比べると原因を絞り込めます。
まとめ
- ブロック変換は
registerBlockTypeのtransformsにfromとtoを書いて実装する(block.json には書けない) type: 'block'が基本で、isMultiBlockで複数選択、prefixで先頭文字からの変換に対応できるisMatchで変換候補を出す条件を絞ると、使い勝手が上がる- コアや他プラグインのブロックには、
blocks.registerBlockTypeフィルターで既存の変換を残したまま追加する wp.blocks.getBlockTransformsで登録を確認し、保存後のブロック検証エラーまでステージング環境で確かめる