Gutenbergにオリジナルなブロックを作成する方法(動的編)

テキスト等を入力、編集できるブロックを作成する方法です。ブロックの基本的な使い方については以下の記事で紹介しているので、まずはこちらを参考にしてください。

Gutenbergにオリジナルなブロックを作成する方法(静的編)

この記事では以下のようなブロックが作るところまでを説明しています。

基本亭には公式チュートリアルをもとに説明していきます。
(公式) → Introducing Attributes and Editable Fields

ブロックのコンポーネントを読み込む

動的なブロックを作成するには、wp_register_scriptの依存関係として、wp-editorを読み込む必要があります。

wp-editorの読み込み

今まではwp-blockswp-elementだけでしたが、そこにwp-editorを追加します。具体的には以下のようなコードとなります。

index.phpコピーwp_register_script(
	'my-gutenberg-script',
	plugins_url( 'block.js', __FILE__ ),
	array( 'wp-blocks', 'wp-element', 'wp-editor' ),
	'1.0.0',
	true
);

window.wp.editorを追加

ブロックを定義するJavaScript側でもwindow.wp.editorという動的ブロック用の引数を追加してあげます。冒頭のfunction( blocks, editor, element )と末尾のwindow.wp.editor,の部分ですね。

block.jsコピー( function( blocks, editor, element ) {
	var el = element.createElement;

	blocks.registerBlockType( 'my-gutenberg/my-example00', {
		title: 'My Gutenberg Example',
		icon: 'universal-access-alt',
		category: 'layout',
		edit: function( props ) {
			return el(
				'p',
				{ className: props.className },
				'Hello World, Pタグのコンテンツです。'
			);
		},
		save: function() {
			return el(
				'p',
				{},
				'Hello World, Pタグのコンテンツです。'
			);
		},
	} );
}(
	window.wp.blocks,
	window.wp.editor,
	window.wp.element
) );

これでブロック用の動的なコンポーネントを使う準備は整いました。

テキストの入力エリアを作成する

ブロック内でテキスト入力させるには、wp-editorの「RichText」を使ってあげます。

まずは先ほど引数として追加したwindow.wp.editorを活用して、RichTextのオブジェクトを定義します。var RichText = editor.RichText;

そして、editsaveにRichTextを適応させます。React等でよく見るpropsで値を管理する方法が使われていますが、こういう書き方だと捉えておけばひとまずはいいかもしれません。

onChange: onChangeContentで入力されるたびに、propsに値を保存する動きがおこっています。

block.jsコピー( function( blocks, editor, element ) {
	var el = element.createElement;
	var RichText = editor.RichText;

	blocks.registerBlockType( 'my-gutenberg/my-example00', {
		title: 'My Gutenberg Example',
		icon: 'universal-access-alt',
		category: 'layout',
		edit: function( props ) {
			var content = props.attributes.content;
			function onChangeContent( newContent ) {
				props.setAttributes( { content: newContent } );
			}

			return el(
				RichText,
				{
					tagName: 'p',
					className: props.className,
					onChange: onChangeContent,
					value: content,
				}
			);
		},
		save: function( props ) {
			return el( RichText.Content, {
				tagName: 'p', value: props.attributes.content,
			} );
		},
	} );
}(
	window.wp.blocks,
	window.wp.editor,
	window.wp.element
) );

ここまで記載すると、冒頭の動画のようなエディタの動きを再現することができます。

ただしこのままだと型が保存されません…。試しにリロードすると、「このブロックには、想定されていないか無効なコンテンツが含まれています。」となってブロックが消えます。

動的なブロックの「型」を指定する

動的なブロックの型を維持するには、attributesを定義することで解決します。
(公式) → Attributes | Block Editor Handbook

先に完成形のコードを見せると以下のとおりです。attributesのパートが追加されていることを確認してください。

block.jsコピー( function( blocks, editor, element ) {
	var el = element.createElement;
	var RichText = editor.RichText;

	blocks.registerBlockType( 'my-gutenberg/my-example00', {
		title: 'My Gutenberg Example',
		icon: 'universal-access-alt',
		category: 'layout',
		attributes: {
			content: {
				type: 'array',
				source: 'children',
				selector: 'p',
			},
		},
		edit: function( props ) {
			var content = props.attributes.content;
			function onChangeContent( newContent ) {
				props.setAttributes( { content: newContent } );
			}

			return el(
				RichText,
				{
					tagName: 'p',
					className: props.className,
					onChange: onChangeContent,
					value: content,
				}
			);
		},
		save: function( props ) {
			return el( RichText.Content, {
				tagName: 'p', value: props.attributes.content,
			} );
		},
	} );
}(
	window.wp.blocks,
	window.wp.editor,
	window.wp.element
) );

基本的に属性がない要素に関してはあまり意識する必要はなく、selectorの項目だけHTMLタグを合わせてあげればOKかと思います。

コピーattributes: {
	content: {
		type: 'array',
		source: 'children',
		selector: 'p', // HTMLタグをあわせる
	},
},

こうやって保存したブロックは、リロードしても型を維持して表示し続けてくれるようになります。動的なブロックを作成する際には必要になるのでattributesの指定を忘れないようにしましょう!

おわり

Gutenbergにオリジナルな動的ブロックを作成する方法でした。ここまで実装できると、ブロックを作っている実感がわいてきますね。

関連の記事