(2023/12/24) この文書の原文は削除されました。以後は「ブロック開発の基本原理」以下を参照ください。便宜上、しばらく訳文を掲載しますが、内容は更新されず、一部古くなっていますので注意してお読みください。
これまでに作ったサンプルブロックはメッセージを変更できないため、あまり面白くありませんでした。このセクションでは RichText フィールドを実装して、ユーザーが好きなメッセージを指定できるようにします。実装の前に、まず重要な、ブロックの状態である「属性」がどのように管理され、どのように変更されるかを理解しましょう。
属性
これまで、edit
関数と save
関数は paragraph 要素のシンプルな表現を返してきました。またこれらの関数が、ブロックの外観の構造の 記述 に責任をもつことも学んできました。もしユーザーがブロックを変更するなら、この構造も変更する必要があるかもしれません。これを実現するには、編集セッションの間中はずっと、ブロックの状態をプレーンな JavaScript オブジェクトとして管理しておき、更新があると、edit
関数を再び呼び出す必要があります。別の言い方をすれば、ブロックの出力は、その属性の関数になります。
ブロックの表現を JavaScript オブジェクトとして管理する場合の課題は、投稿の保存されたコンテンツから再びこのオブジェクトを取り出さなければならない点です。これを実現するのがブロックタイプの attributes
プロパティです。
attributes: {
content: {
type: 'string',
source: 'html',
selector: 'p',
},
},
新しいブロックタイプを登録する際、attributes
プロパティで edit
関数や save
関数で受け取る属性オブジェクトの形を記述します。それぞれの値はブロックのマークアップから希望の値を見つける source 関数 になります。
上のコード例ではエディターのロード中に、保存された投稿のマークアップの中の paragraph 要素の HTML から content
値が取り出されます。
コンポーネントと RichText コンポーネント
これまでのサンプルでは createElement
関数を使用して DOM ノードを作成しましたが、この動きを「コンポーネント」にカプセル化することができます。この抽象化により共通の動作を共有しやすくなり、複雑さを自己完結したユニット内に隠す事ができます。
ブロックの実装に利用できるコンポーネントが多数あります。以下のサンプルではそのうちの1つ RichText
コンポーネントを使用します。RickTest
コンポーネントは wp-editor
パッケージの一部です。
RichText
コンポーネントはパワーアップした textarea
要素と見なせます。ここでは太字、車体、ハイパーリンクなどのリッチコンテンツを編集できます。
ES5 コードを使用して RichText
コンポーネントを使用する場合は、wp_register_script
呼び出しの際の登録スクリプトハンドルの依存性配列に wp-block-editor
を追加してください。
// automatically load dependencies and version
$asset_file = include( plugin_dir_path( __FILE__ ) . 'build/index.asset.php');
wp_register_script(
'gutenberg-examples-03-esnext',
plugins_url( 'build/index.js', __FILE__ ),
$asset_file['dependencies'],
$asset_file['version']
);
忘れずに register_block_type
の editor_script
ハンドルを gutenberg-examples-03-esnext
に更新してください。
振る舞いをコンポーネントとして実装することで、ブロック開発者は編集可能フィールドに対するきめ細かい制御が可能になります。ブロックでは RichText
が不要かもしれませんし、それぞれが状態全体の一部を操作する多くの独立した RichText
要素が必要かもしれません。
RickText
はネストしたノードが許されるため、多くの場合、保存されたコンテンツから取り出す際に html
属性ソースと組み合わせて使用されます。また RichText.Content
は save
関数の中で RickText の出力に使用されます。
Example 03 の完全なブロック定義を以下に示します。
import { registerBlockType } from '@wordpress/blocks';
import { useBlockProps, RichText } from '@wordpress/block-editor';
registerBlockType( 'gutenberg-examples/example-03-editable-esnext', {
apiVersion: 3,
title: 'Example: Editable (esnext)',
icon: 'universal-access-alt',
category: 'design',
attributes: {
content: {
type: 'string',
source: 'html',
selector: 'p',
},
},
example: {
attributes: {
content: 'Hello World',
},
},
edit: ( props ) => {
const {
attributes: { content },
setAttributes,
className,
} = props;
const blockProps = useBlockProps();
const onChangeContent = ( newContent ) => {
setAttributes( { content: newContent } );
};
return (
<RichText
{ ...blockProps }
tagName="p"
onChange={ onChangeContent }
value={ content }
/>
);
},
save: ( props ) => {
const blockProps = useBlockProps.save();
return (
<RichText.Content
{ ...blockProps }
tagName="p"
value={ props.attributes.content }
/>
);
},
} );