ブロックは「ブロックコンテキスト」を使用して、継承先のブロックでも消費可能な値を提供できます。子や孫のブロックは、ハードコードされた値に依存せず、また明示的に提供元のブロックを知ることなく値を継承できます。
この機能は特に「フルサイト編集」で有用です。たとえば表示される投稿の種類によってブロックの内容を変える場合があります。ブログ用のテンプレートであれば多くの異なる投稿の抜粋を表示します。ブロックコンテキストを使用すると、単一の「投稿抜粋」ブロックで、継承した投稿 ID を基に投稿のコンテンツを表示できます。
React コンテキスト を知っていれば、ブロックコンテキストは多くで同じアイデアを採用しています。実際、ブロックコンテキストのクライアント側ブロックエディターの実装は非常に簡単な React コンテキストのアプリケーションです。ブロックコンテキストは以下の例で見るようにサーバー側 render_callback
実装でもサポートされています。
ブロックコンテキストの定義
ブロックコンテキストはブロックの登録設定内で定義されます。ブロックはコンテキスト値を提供したり継承した値を消費することができます。
ブロックコンテキストの提供
コンテキスト値を提供するには、登録設定の中で providesContext
プロパティに割り当てます。providesContext
プロパティはコンテキスト名をブロック自身の属性のどれか1つとマップするオブジェクトです。属性値に関連付けられた値は子孫のブロックで利用でき、同じコンテキスト名で参照できます。現行ではブロックコンテキストはブロック自身の属性から派生した値のみをサポートしますが、将来的には拡張されコンテキスト値の追加ソースをサポートする予定です。
attributes: {
recordId: {
type: 'number',
},
},
providesContext: {
'my-plugin/recordId': 'recordId',
},
完全なサンプルコードは以下のセクションを参照してください。
上の例で見るようにコンテキストキーには名前空間を含めることが推奨されます。他のプラグインや WordPress で提供されるデフォルトのコンテキスト値との潜在的な衝突を防ぎます。コンテキストの名前空間は、プラグイン固有にしてください。多くの場合、ブロックの名前と同じものが使用されます。
Block コンテキストの消費
ブロックは、登録設定の中で usesContext
プロパティを割り当てることで先祖のプロバイダーからコンテキスト値を継承します。このときプロパティには、ブロックが継承するコンテキスト名の配列を割り当てる必要があります。
registerBlockType('my-plugin/record-title', {
title: 'Record Title',
category: 'widgets',
usesContext: ['my-plugin/recordId'],
Block コンテキストの使用
ブロックが継承するコンテキストを定義すると、edit
(JavaScript) や render_callback
(PHP) の実装の中でアクセスできます。コンテキストは、ブロックで定義されたコンテキスト値のオブジェクト (JavaScript) または連想配列 (PHP) として提供されます。注意: コンテキスト値は、ブロックが値の継承の意志を明示的に定義した場合にのみ利用可能です。
注意: ブロックコンテキストは save
で利用できません。
JavaScript
registerBlockType('my-plugin/record-title', {
edit({ context }) {
return 'The record ID: ' + context['my-plugin/recordId'];
},
PHP
ブロックのコンテキスト値は、render_callback
関数の第3引数として渡される $block
引数の context
プロパティから利用可能です。
register_block_type( 'my-plugin/record-title', array(
'render_callback' => function( $attributes, $content, $block ) {
return 'The current record ID is: ' . $block->context['my-plugin/recordId'];
},
) );
例
record
ブロックを作成します。
npm init @wordpress/block --namespace my-plugin record
cd record
src/index.js
を編集します。recordId
属性とprovidesContext
プロパティをregisterBlockType
関数内に挿入し、末尾にrecord-title
ブロックの登録を追加します。
registerBlockType( 'my-plugin/record', {
// ... cut ...
attributes: {
recordId: {
type: 'number',
},
},
providesContext: {
'my-plugin/recordId': 'recordId',
},
/**
* @see ./edit.js
*/
edit: Edit,
/**
* @see ./save.js
*/
save,
} );
registerBlockType( 'my-plugin/record-title', {
title: 'Record Title',
category: 'widgets',
usesContext: [ 'my-plugin/recordId' ],
edit( { context } ) {
return 'The record ID: ' + context[ 'my-plugin/recordId' ];
},
save() {
return null;
},
} );
record
ブロックのsrc/edit.js
を編集します。Edit
関数を以下のコードで置き換えます。
import { TextControl } from '@wordpress/components';
import { InnerBlocks } from '@wordpress/block-editor';
export default function Edit( props ) {
const MY_TEMPLATE = [ [ 'my-plugin/record-title', {} ] ];
const {
attributes: { recordId },
setAttributes,
} = props;
return (
<div>
<TextControl
label={ __( 'Record ID:' ) }
value={ recordId }
onChange={ ( val ) =>
setAttributes( { recordId: Number( val ) } )
}
/>
<InnerBlocks template={ MY_TEMPLATE } templateLock="all" />
</div>
);
}
record
ブロックのsrc/save.js
を編集します。save
関数を以下のコードで置き換えます。
export default function save( props ) {
return <p>The record ID: { props.attributes.recordId }</p>;
}
- 新しい投稿を作成し、
record
ブロックを追加します。テキストボックスに数を入力すると、同じ数が下のrecord-title
ブロックに表示されます。