許可されたブロック
allowedBlocks
プロパティを使用すると、block.json
の allowedBlocks
フィールドに加えて、このブロックの直接の子孫として挿入できるブロックをさらに制限できます。これは、各ブロックごとに動的に許可されたブロックのリストを決定するのに役立ちます。たとえば、ブロック属性によって決定されます:
const { allowedBlocks } = attributes;
//...
<InnerBlocks allowedBlocks={ allowedBlocks } />;
許可されたブロックのリストが常に同じである場合は、代わりに allowedBlocks
ブロック設定 を使用してください。
方向
デフォルトでは、InnerBlocks
はそのブロックが縦のリストで表示されることを期待します。有効な使用例は、内側のブロックが横に表示されるようにスタイルを設定することです。たとえば、内側のブロックラッパーに CSS フレックスまたはグリッドプロパティを追加することによってです。このようにブロックがスタイル設定されている場合、orientation
プロパティを設定して、横レイアウトが使用されていることを示すことができます:
<InnerBlocks orientation="horizontal" />
このプロパティを指定しても内側のブロックのレイアウトには影響しませんが、子ブロックのブロックムーバーアイコンが横に表示され、ドラッグアンドドロップが正しく機能することが保証されます。
デフォルトブロック
デフォルトでは、InnerBlocks
はブロックアペンダーがクリックされたときに許可されたブロックのリストを開きます。defaultBlock
プロパティを使用して、初期のブロックアペンダーがクリックされたときに挿入されるデフォルトブロックとその属性を変更できます。たとえば:
<InnerBlocks defaultBlock={['core/paragraph', {placeholder: "Lorem ipsum..."}]} directInsert />
デフォルトでは、この動作は directInsert
プロパティが true
に設定されるまで無効です。これにより、デフォルトブロックを挿入すべきかどうかの条件を指定できます。
テンプレート
テンプレートプロパティを使用して、挿入時に InnerBlocks コンポーネントを事前に埋めるブロックのセットを定義します。ブロックに属性を設定してその使用を定義できます。以下の例は、InnerBlocks コンポーネントを使用した書評テンプレートで、ブロックの使用を示すためにプレースホルダー値を設定しています。
const MY_TEMPLATE = [
[ 'core/image', {} ],
[ 'core/heading', { placeholder: 'Book Title' } ],
[ 'core/paragraph', { placeholder: 'Summary' } ],
];
//...
edit: () => {
return (
<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' )
);
} );
ブロック内の親、先祖、子供の関係を使用する
InnerBlocks を使用する一般的なパターンは、親ブロックが挿入されている場合にのみ利用可能なカスタムブロックを作成することです。これにより、ビルダーはブロック間の関係を確立し、ネストされたブロックの発見可能性を制限できます。ビルダーが使用できる関係は、parent
、ancestor
、および allowedBlocks
の 3 つです。違いは次のとおりです:
parent
を割り当てると、ネストされたブロックは 親の直接の子孫 としてのみ使用および挿入できることを示します。ancestor
を割り当てると、ネストされたブロックは 親の子孫 としてのみ使用および挿入できることを示します。allowedBlocks
を割り当てると、逆方向の関係を示します。つまり、どのブロックがこのブロックの 直接の子孫 として使用および挿入できるかを示します。
parent
と ancestor
の主な違いは、parent
がより細かい特異性を持ち、ancestor
はネストされた階層においてより大きな柔軟性を持つことです。
親ブロック関係の定義
これの例は、parent
ブロック設定が割り当てられたカラムブロックです。これにより、カラムブロックは親のカラムブロック内のネストされた直接の子孫としてのみ利用可能になります。そうでなければ、カラムブロックはブロックインサータ内のオプションとして利用できません。参照用に カラムコード を参照してください。
直接の子孫ブロックを定義する場合は、parent
ブロック設定を使用して、どのブロックが親であるかを定義します。これにより、ネストされたブロックが定義された InnerBlock の外でインサータに表示されるのを防ぎます。
{
"title": "Column",
"name": "core/column",
"parent": [ "core/columns" ],
// ...
}
先祖ブロック関係の定義
これの例は、ancestor
ブロック設定が割り当てられたコメント著者名ブロックです。これにより、コメント著者名ブロックは先祖のコメントテンプレートブロック内のネストされた子孫としてのみ利用可能になります。そうでなければ、コメント著者名ブロックはブロックインサータ内のオプションとして利用できません。参照用に コメント著者名コード を参照してください。
ancestor
関係により、コメント著者名ブロックは階層ツリーのどこにでも配置でき、親のコメントテンプレートブロックの直接の子供だけではなく、ブロックインサータ内での利用可能性を制限し、コメントテンプレートブロックが利用可能な場合にのみ挿入オプションとして表示されます。
子孫ブロックを定義する場合は、ancestor
ブロック設定を使用します。これにより、ネストされたブロックが定義された InnerBlock の外でインサータに表示されるのを防ぎます。
{
"title": "Comment Author Name",
"name": "core/comment-author-name",
"ancestor": [ "core/comment-template" ],
// ...
}
子ブロック関係の定義
これの例は、allowedBlocks
ブロック設定が割り当てられたナビゲーションブロックです。これにより、ナビゲーションブロックの直接の子孫として利用可能なブロックタイプの特定のサブセットのみが利用可能になります。参照用に ナビゲーションコード を参照してください。
allowedBlocks
設定は、カスタムブロックのビルダーによって拡張できます。カスタムブロックは、blocks.registerBlockType
フィルターにフックして、ナビゲーションの利用可能な子供に自分自身を追加できます。
可能な子孫ブロックのセットを定義する場合は、allowedBlocks
ブロック設定を使用します。これにより、新しい子ブロックを挿入する際にインサータに表示されるブロックが制限されます。
{
"title": "Navigation",
"name": "core/navigation",
"allowedBlocks": [ "core/navigation-link", "core/search", "core/social-links", "core/page-list", "core/spacer" ],
// ...
}
React フックの使用
InnerBlocks
コンポーネントの代わりに、useInnerBlocksProps
という React フックを使用できます。このフックを使用すると、内側のブロック領域のマークアップをより制御できます。
useInnerBlocksProps
は、@wordpress/block-editor
パッケージからエクスポートされ、InnerBlocks
コンポーネント自体と同様に、コンポーネントが行うすべてのことをサポートします。また、useBlockProps
フックのように機能します。
基本的な useInnerBlocksProps
フックの使用法は次のとおりです。
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>
);
},
} );
このフックは、useBlockProps
フックから返されたオブジェクトを useInnerBlocksProps
フックに渡すこともできます。これにより、作成する必要のある要素の数が減ります。
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} />
);
},
} );
上記のコードは、エディターで次のマークアップをレンダリングします:
<div>
<!-- Inner Blocks get inserted here -->
</div>
フックアプローチを使用するもう一つの利点は、返された値が単なるオブジェクトであり、オブジェクトから React 子供を取得するために分解できることです。このプロパティには、実際の子内ブロックが含まれているため、内側のブロックと同じレベルに要素を配置できます。
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>
);
},
// ...
} );
<div>
<!-- Inner Blocks get inserted here -->
<!-- The custom html gets rendered on the same level -->
</div>