ネストしたブロック: InnerBlocks の使用
ネストしたブロック: InnerBlocks の使用 コメント
他のブロックをネストするブロックを作成するには InnerBlocks コンポーネントを使用します。このコンポーネントは「カラム」ブロックや「ソーシャルリンク」ブロックなど、他のブロックを含むブロックで使用されています。
注意: 単一のブロックは、1つの InnerBlocks
コンポーネントのみを含むことができます。
基本的な InnerBlocks の使用方法
JSX
import { registerBlockType } from '@wordpress/blocks';
import { InnerBlocks, useBlockProps } from '@wordpress/block-editor';
registerBlockType( 'gutenberg-examples/example-06', {
// ...
edit: () => {
const blockProps = useBlockProps();
return (
<div { ...blockProps }>
<InnerBlocks />
</div>
);
},
save: () => {
const blockProps = useBlockProps.save();
return (
<div { ...blockProps }>
<InnerBlocks.Content />
</div>
);
},
} );
Plain
( function ( blocks, element, blockEditor ) {
var el = element.createElement;
var InnerBlocks = blockEditor.InnerBlocks;
var useBlockProps = blockEditor.useBlockProps;
blocks.registerBlockType( 'gutenberg-examples/example-06', {
title: 'Example: Inner Blocks',
category: 'design',
edit: function () {
var blockProps = useBlockProps();
return el( 'div', blockProps, el( InnerBlocks ) );
},
save: function () {
var blockProps = useBlockProps.save();
return el( 'div', blockProps, el( InnerBlocks.Content ) );
},
} );
} )( window.wp.blocks, window.wp.element, window.wp.blockEditor );
許可されるブロック
ALLOWED_BLOCKS
プロパティを使用すると、InnerBlock 内で許可されるブロックの集合を定義できます。インサーターに含まれるブロックはリストされたブロックのみに制限され、その他のすべてのブロックは表示されません。
const ALLOWED_BLOCKS = [ 'core/image', 'core/paragraph' ];
//...
<InnerBlocks allowedBlocks={ ALLOWED_BLOCKS } />;
orientation
デフォルトでは、InnerBlocks
は、縦のリストとしてブロックが表示されることを期待しています。また、内部ブロックのラッパーに CSS flex や grid プロパティを追加して、横に並べて表示するようスタイリングすることもできます。ブロックを横に並べる場合は、horizontal レイアウトが使用されることを示すために orientation
プロパティを使用してください。
<InnerBlocks orientation="horizontal" />
このプロパティを指定しても、内側のブロックのレイアウトには影響しませんが、子ブロックのブロック移動アイコンが水平に表示され、また、ドラッグアンドドロップが正しく動作するようになります。
テンプレート
template プロパティを使用して、InnerBlocks コンポーネントが挿入された際にデフォルトで含まれるブロックの集合を定義できます。ブロックの属性を設定して使用例を定義できます。次の例は InnerBlocks コンポーネントを使用した本のレビューのテンプレートです。placeholder 値を設定してブロックの使用例を示しています。
JSX
const MY_TEMPLATE = [
[ 'core/image', {} ],
[ 'core/heading', { placeholder: 'Book Title' } ],
[ 'core/paragraph', { placeholder: 'Summary' } ],
];
//...
edit: () => {
return (
<InnerBlocks
template={ MY_TEMPLATE }
templateLock="all"
/>
);
},
Plain
const MY_TEMPLATE = [
[ 'core/image', {} ],
[ 'core/heading', { placeholder: 'Book Title' } ],
[ 'core/paragraph', { placeholder: 'Summary' } ],
];
//...
edit: function( props ) {
return el(
InnerBlocks,
{
template: MY_TEMPLATE,
templateLock: "all",
}
);
},
templateLock
プロパティを使用するとテンプレートをロックできます。テンプレートを完全にロックするには all
を使用します。insert
は追加ブロックのインサートを禁止しますが、既存のブロックは並べ替えられます。詳細については templateLock のドキュメントを参照してください。
投稿テンプレート
InnerBlocks
とは関連しませんが、投稿タイプごとに投稿テンプレートを作れます。投稿テンプレートはブロックエディターにブロックの集合をプリロードします。
InnerBlocks
テンプレートは、作成した単一ブロック内のコンポーネントのためのもので、投稿のそれ以外の箇所にはユーザーが好きなブロックを含められます。投稿テンプレートを使用すると、投稿全体を定義したテンプレートのみに固定できます。
add_action( 'init', function() {
$post_type_object = get_post_type_object( 'post' );
$post_type_object->template = array(
array( 'core/image' ),
array( 'core/heading' )
);
} );
ブロックでの parent 関係と ancestor 関係の使用
一般的な InnerBlock の使用パターンとして、親ブロックが挿入された場合にのみ使用可能なカスタムブロックの作成があります。これによりビルダーは、ブロック間の関係を確立し、ネストするブロックの発現を制限できます。現在、ビルダーが使用できる関係には parent
(親) と ancestor
(先祖) の2つがあります。違いは以下のとおりです。
parent
を割り当てると、ネストするブロックが 親の直接の子孫 としてのみ使用、挿入できることの表明になります。ancestor
を割り当てると、ネストするブロックが 親の子孫 としてのみ使用、挿入できることの表明になります。
parent
と ancestor
の主な違いとして、parent
はより細かな特異性を持ち、ancestor
はそのネスト階層においてより大きな柔軟性を持ちます。
parent ブロック関係の定義
この例に「カラム (Column)」ブロックがあり、parent
ブロック設定が割り当てられています。これにより、Column ブロックは、親の「カラム (Columns、複数形)」ブロックのネストした直接の子孫としてのみ利用できます。Columns ブロック以外では、Column ブロックはブロックインサーターのオプションとして利用できません。Column ブロックのコードを参照してください。
直接の子孫ブロックを定義する際には、parent
ブロック設定を使用して、どのブロックが親であるかを定義します。これでネストするブロックは、定義された InnerBlock 以外でインサーター内には表示されません。
{
"title": "Column",
"name": "core/column",
"parent": [ "core/columns" ],
// ...
}
ancestor ブロック関係の定義
この例に「コメントの投稿者名」ブロックがあり、ancestor
ブロック設定が割り当てられています。これにより、コメントの投稿者名ブロックは、その祖先であるコメントテンプレートブロックのネストされた子孫としてのみ利用できます。コメントテンプレートブロック以外では、コメントの投稿者名ブロックはブロックインサータのオプションとして利用できません。コメントの投稿者名ブロックのコードを参照してください。
ancestor
関係により、コメントの投稿者名ブロックは階層ツリーのどこにでも置けます。親のコメントテンプレートブロックの直接の子のみには縛られません。ただしコメントテンプレートブロックがある場合にのみ、ブロックインサーター内で挿入可能なオプションとして表示されます。
子孫ブロックを定義する際には、ancestor
ブロック設定を使用します。これでネストするブロックは、定義された InnerBlock 以外でインサーター内には表示されません。
{
"title": "Comment Author Name",
"name": "core/comment-author-name",
"ancestor": [ "core/comment-template" ],
// ...
}
React フックの使用
react フック useInnerBlocksProps
を、InnerBlocks
コンポーネントの代わりに使用できます。このフックを使用すると、インナーブロック領域のマークアップをより詳細に制御できます。
useInnerBlocksProps
は InnerBlocks
コンポーネント自身と同様に @wordpress/block-editor
パッケージからエクスポートされ、InnerBlocks
コンポーネントのすべてをサポートします。また、useInnerBlocksProps
は useBlockProps
フックと同様に機能します。
基本的な useInnerBlocksProps
フックの使用方法です。
JSX
import { registerBlockType } from '@wordpress/blocks';
import { useBlockProps, useInnerBlocksProps } from '@wordpress/block-editor';
registerBlockType( 'gutenberg-examples/example-06', {
// ...
edit: () => {
const blockProps = useBlockProps();
const innerBlocksProps = useInnerBlocksProps();
return (
<div { ...blockProps }>
<div {...innerBlocksProps} />
</div>
);
},
save: () => {
const blockProps = useBlockProps.save();
const innerBlocksProps = useInnerBlocksProps.save();
return (
<div { ...blockProps }>
<div {...innerBlocksProps} />
</div>
);
},
} );
Plain
( function ( blocks, element, blockEditor ) {
var el = element.createElement;
var InnerBlocks = blockEditor.InnerBlocks;
var useBlockProps = blockEditor.useBlockProps;
var useInnerBlocksProps = blockEditor.useInnerBlocksProps;
blocks.registerBlockType( 'gutenberg-examples/example-06', {
title: 'Example: Inner Blocks',
category: 'design',
edit: function () {
var blockProps = useBlockProps();
var innerBlocksProps = useInnerBlocksProps();
return el( 'div', blockProps, el( 'div', innerBlocksProps ) );
},
save: function () {
var blockProps = useBlockProps.save();
var innerBlocksProps = useInnerBlocksProps.save();
return el( 'div', blockProps, el( 'div', innerBlocksProps ) );
},
} );
} )( window.wp.blocks, window.wp.element, window.wp.blockEditor );
また、useBlockProps
から返されたオブジェクトを useInnerBlocksProps
フックに渡せます。この手法により作成する要素の数を減らせます。
JSX
import { registerBlockType } from '@wordpress/blocks';
import { useBlockProps, useInnerBlocksProps } from '@wordpress/block-editor';
registerBlockType( 'gutenberg-examples/example-06', {
// ...
edit: () => {
const blockProps = useBlockProps();
const innerBlocksProps = useInnerBlocksProps( blockProps );
return (
<div {...innerBlocksProps} />
);
},
save: () => {
const blockProps = useBlockProps.save();
const innerBlocksProps = useInnerBlocksProps.save( blockProps );
return (
<div {...innerBlocksProps} />
);
},
} );
Plain
( function ( blocks, element, blockEditor ) {
var el = element.createElement;
var InnerBlocks = blockEditor.InnerBlocks;
var useBlockProps = blockEditor.useBlockProps;
var useInnerBlocksProps = blockEditor.useInnerBlocksProps;
blocks.registerBlockType( 'gutenberg-examples/example-06', {
// ...
edit: function () {
var blockProps = useBlockProps();
var innerBlocksProps = useInnerBlocksProps();
return el( 'div', innerBlocksProps );
},
save: function () {
var blockProps = useBlockProps.save();
var innerBlocksProps = useInnerBlocksProps.save();
return el( 'div', innerBlocksProps );
},
} );
} )( window.wp.blocks, window.wp.element, window.wp.blockEditor );
上のコードはエディター内で次のマークアップをレンダーします。
<div>
<!-- Inner Blocks get inserted here -->
</div>
フックによるアプローチを使用するもう一つの利点は、単なるオブジェクトである戻り値を分解して、react children
を取得できる点です。このプロパティには実際の子のインナーブロックが含まれているため、インナーブロックと同じレベルに要素を配置できます。
JSX
import { registerBlockType } from '@wordpress/blocks';
import { useBlockProps, useInnerBlocksProps } from '@wordpress/block-editor';
registerBlockType( 'gutenberg-examples/example-06', {
// ...
edit: () => {
const blockProps = useBlockProps();
const { children, ...innerBlocksProps } = useInnerBlocksProps( blockProps );
return (
<div {...innerBlocksProps}>
{ children }
<!-- Insert any arbitrary html here at the same level as the children -->
</div>
);
},
// ...
} );
Plain
( function ( blocks, element, blockEditor ) {
var el = element.createElement;
var InnerBlocks = blockEditor.InnerBlocks;
var useBlockProps = blockEditor.useBlockProps;
var useInnerBlocksProps = blockEditor.useInnerBlocksProps;
blocks.registerBlockType( 'gutenberg-examples/example-06', {
// ...
edit: function () {
var blockProps = useBlockProps();
var { children, ...innerBlocksProps } = useInnerBlocksProps( blockProps );
return el(
'div',
innerBlocksProps,
children,
el(
'div',
{},
'<!-- Insert any arbitrary html here at the same level as the children -->',
)
);
},
// ...
} );
} )( window.wp.blocks, window.wp.element, window.wp.blockEditor );
<div>
<!-- Inner Blocks get inserted here -->
<!-- The custom html gets rendered on the same level -->
</div>
最終更新日: