Gutenbergの最大の特徴は入れ子構造を取る事ができる事です。
他のブロックエディタでは入れ子にする事ができない事が多く、グーテンベルクが複雑なコンテンツを制作する事が出来るのはこの入れ子という仕組みがあるからといってもいいかもしれません。
ですので、入れ子ブロックの作り方はマスターしておきたいところです。
この記事では、入れ子可能なブロックの制作方法について解説します。
Gutenbergでは入れ子に対して○○ブロックのみ追加可能というように、制限を掛ける事が可能です。
これにより、繰り返しカスタムフィールドの上位互換が制作可能です。
Advanced Custom Fieldsの繰り返しは有料となってしまいましたが、これでもうお金を払う必要はありません。
公式ドキュメント:Nested Blocks: Using InnerBlocks
開発環境やブロックの基本的な制作
この記事では複数のブロックを制作する必要があります。
複数のブロックを制作出来る開発環境や、ブロックの基本的な作り方などの知識はすでにある前提で進めていきます。
もし、基本的な作り方や環境構築の方法を知りたい方は以下の記事を参考にしてください。
InnerBlocks
入れ子可能なブロックを制作することは簡単でInnerBlocksコンポーネントを使用する事で実装できます。
import { InnerBlocks, useBlockProps } from '@wordpress/block-editor';
export default function Edit() {
const blockProps = useBlockProps({
className: 'c-inner-blocks',
});
return (
<div {...blockProps}>
<InnerBlocks />
</div>
);
};
Allowed Blocksで入れ子制御
Allowed Blocksを指定する事で子供として入るブロックを制限する事が可能です。
const ALLOWED_BLOCKS = ['Block名', 'Block名'];
<InnerBlocks
allowedBlocks={ALLOWED_BLOCKS}
/>
上のようにallowedBlocksに許可したいブロックの名前を配列形式で渡す事で配列に記載した名前のブロックしか入れる事ができなくなります。
ブロックの名前はWordPressがデフォルトで用意してるブロックなら「core/***」オリジナルで制作したなら「プラグイン名/ブロック名」となります。
デフォルトブロックは↓の公式ページを参考にしてください。
ページのnameの部分の値がブロックの名前です。
templateでブロックのテンプレートを作る
templateを使用する事で元々ある複数のブロックを組み合わせてテンプレートのようなものを制作する事が可能です。
const TEMPLATE = [
[ 'core/image', {} ],
[ 'core/heading', { placeholder: 'Book Title' } ],
[ 'core/paragraph', { placeholder: 'Summary' } ],
];
return (
<div {...blockProps}>
<InnerBlocks
template={ TEMPLATE }
/>
</div>
);
デフォルトで用意されている、画像、ヘディング、段落ブロックを使用してリンクパネルのようなものを制作するサンプルです。
templateLock
テンプレートや子ブロックの挿入を禁止する事が可能です。
| contentOnly | 操作を阻止します。さらに、コンテンツを持たないブロックタイプはリストビューから隠され、ブロックリスト内でフォーカスを得ることができなくなります。他のロックタイプとは異なり、これは子プロセスによる上書きはできません。 |
| all | すべての操作を阻止します。新しいブロックを挿入することはできません。既存のブロックを移動したり、削除したりすることができます。 |
| insert | ブロックの挿入や削除はできませんが、既存のブロックを移動することは可能です。 |
| false | 親ブロックがロックを含んでいても、InnerBlocks領域にロックが適用されないようにします。( ブール値 ) |
親子関係を指定する
親子関係を指定する事でカスタムフィールドの繰り返しフィールドのような事が可能となります。
ここでは例として順序を表現するステップブロックを制作してみましょう。
ステップブロックのイメージは以下です。

まずブロックを追加すると、プラスボタンが表れます。

プラスボタンをクリックするとステップ1としてタイトルや本文を記入するエリアが表示されます。

さらにプラスボタンをクリックする事でステップをいくつも追加する事が可能です。
親ブロックを制作する
ブロックの名前をstepとしてブロックを制作します。
step
└── src
├── index.js
├── edit.js
├── save.js
└── block.json
edit.jsで以下のようにInnerBlocksをセットします。
許可ブロックはこの後制作するstep-contentのみを許可します。
const ALLOWED_BLOCKS = ['create-block/step-content'];
<div {...blockProps}>
<InnerBlocks
allowedBlocks={ALLOWED_BLOCKS}
templateLock={false}
/>
</div>
子ブロックを制作する
step-content
└── src
├── index.js
├── edit.js
├── save.js
└── block.json
親子関係を持つ子ブロックを作る時は少し注意が必要です。
多くの場合、子ブロックは親ブロックが存在しない場合はブロック一覧に出力する必要はなく、特定の親の中でのみ使用するという制限を掛けます。
そのような設定をする場合はblock.jsonにparentを追加します。
{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "create-block/step-content",
"parent": ["create-block/step"], // こちらを追加
"version": "0.1.0",
"title": "ステップコンテンツ",
省略 ...
}
parentに配列形式で名前をセットする事で設定した親の中でしかそのブロックを使用する事ができなくなります。
子供のブロックに関しては通常通りedit.jsを制作します。
もちろん子供ブロックの中でもInnerBlocksを使用する事ができますので、その中にさらに繰り返しブロックを制作する事も可能です。
ancestor
block.jsonのparentは直接の親を指定するものですが、似たようなものにancestorがあります。
ancestorを使用すると、直接ではなく、先祖に指定したブロックがあれば使用する事が出来るような設定をする事が可能です。
ですので、間に別のブロックを挟む事が可能になります。