ダイナミックブロックの作成

ダイナミックブロックは、フロントエンドでレンダーされる際に、動的に構造とコンテンツを構築するブロックです。

ダイナミックブロックの代表的な使用例が2つあります。

  1. 投稿が更新されていなくてもコンテンツを変更するブロック。WordPress から例を挙げると「最近の更新」ブロックです。新しい投稿が公開されると、このブロックを使用しているすべての箇所が更新されます。
  2. HTML、CSS、JS などのコードの更新が、Web サイトのフロントエンド側にすぐに反映されるブロック。たとえば新しいクラスの追加、HTML 要素の追加、その他の方法によるレイアウトの変更でブロックの構造を更新しても、ダイナミックブロックを使用していれば、サイト内のすべてのブロックの使用箇所に、即座に変更を適用できます (ダイナミックブロックを使用せずにブロックコードを更新すると、Gutenberg の妥当性検証プロセスが適用され、ユーザーに検証メッセージ「ブロックの外観は外部で更新されました」が表示されます)。

ほとんどのダイナミックブロックで save コールバック関数は null を返してください。これはエディターに、ブロックの属性のみをデータベースに保存するよう通知します。属性はサーバー側レンダリングコールバック内に渡されるため、サイトのフロントエンドでのブロックの表示方法を決定できます。null を返すとエディターはブロックのマークアップの妥当性検査プロセスをスキップするため、頻繁にマークアップを変更する際の問題を回避できます。

ダイナミックブロック内で InnerBlocks を使用している場合には、<InnerBlocks.Content/> を使用して save コールバック関数内で InnerBlocks を保存する必要があります。

ブロックの HTML 表現も保存できます。この HTML は、サーバー側レンダリングコールバックがあると、そのコールバックの出力で置換されます。しかしブロックを無効化したり、レンダリングコールバックを削除するとレンダーされます。

ブロックの属性は、そのブロックに保存したい任意のコンテツや設定に使用できます。上で紹介した最新の投稿ブロックの例では、属性としてフロントエンドに表示したい最新の投稿数を保存できます。また2番目の例では、フロントエンドで表示したいコンテンツの部品、たとえば見出しテキスト、段落テキスト、画像、URLのそれぞれに属性を使用できます。

次のコード例は、最後の投稿のみをリンクとして表示するダイナミックブロックを作成します。

import { registerBlockType } from '@wordpress/blocks';
import { useSelect } from '@wordpress/data';
import { useBlockProps } from '@wordpress/block-editor';

registerBlockType( 'gutenberg-examples/example-dynamic', {
	apiVersion: 3,
	title: 'Example: last post',
	icon: 'megaphone',
	category: 'widgets',

	edit: () => {
		const blockProps = useBlockProps();
		const posts = useSelect( ( select ) => {
			return select( 'core' ).getEntityRecords( 'postType', 'post' );
		}, [] );

		return (
			<div { ...blockProps }>
				{ ! posts && 'Loading' }
				{ posts && posts.length === 0 && 'No Posts' }
				{ posts && posts.length > 0 && (
					<a href={ posts[ 0 ].link }>
						{ posts[ 0 ].title.rendered }
					</a>
				) }
			</div>
		);
	},
} );

これはダイナミックブロックですのでクライアントのデフォルトの save 実装をオーバーライドする必要はありません。代わりにサーバーコンポーネントが必要です。サイトのフロントエンド内のコンテンツは register_block_type の render_callback プロパティに呼び出される関数に依存します。

<?php

/**
 * Plugin Name: Gutenberg examples dynamic
 */

function gutenberg_examples_dynamic_render_callback( $block_attributes, $content ) {
	$recent_posts = wp_get_recent_posts( array(
		'numberposts' => 1,
		'post_status' => 'publish',
	) );
	if ( count( $recent_posts ) === 0 ) {
		return 'No posts';
	}
	$post = $recent_posts[ 0 ];
	$post_id = $post['ID'];
	return sprintf(
		'<a class="wp-block-my-plugin-latest-post" href="%1$s">%2$s</a>',
		esc_url( get_permalink( $post_id ) ),
		esc_html( get_the_title( $post_id ) )
	);
}

function gutenberg_examples_dynamic() {
	// automatically load dependencies and version
	$asset_file = include( plugin_dir_path( __FILE__ ) . 'build/index.asset.php');

	wp_register_script(
		'gutenberg-examples-dynamic',
		plugins_url( 'build/block.js', __FILE__ ),
		$asset_file['dependencies'],
		$asset_file['version']
	);

	register_block_type( 'gutenberg-examples/example-dynamic', array(
		'api_version' => 3,
		'editor_script' => 'gutenberg-examples-dynamic',
		'render_callback' => 'gutenberg_examples_dynamic_render_callback'
	) );

}
add_action( 'init', 'gutenberg_examples_dynamic' );


いくつか注意点があります。

  • 依然として edit 関数はエディターのコンテキストにおけるブロックの外観を表示します (レンダーバージョンとまったく異なる場合もあります。これはブロック作者の好みによります)
  • 組み込みの save 関数は null を返すだけです。これはレンダリングがサーバー側で実行されるためです。
  • サーバー側レンダリングは、ブロックとブロックの内部コンテンツを引数に取る関数で、ショートコードに似たマークアップを返します。

注意: 色やボーダー、スペースなどの一般的なカスタマイズ設定では、次の章で見るように、より効率的に同じ機能を提供するブロックサポートを使用できます。

ブロックエディター内でのライブレンダリング

Gutenberg 2.8 は <ServerSideRender> ブロックを追加しました。JavaScript の代わりに PHP を使用してサーバー上でレンダリングを実行します。

サーバー側レンダーはフォールバックです。常に JavaScript によるクライアントサイドレンダリングが好まれます。クライアントレンダリングは速く、エディターの操作性が高くなります).

import { registerBlockType } from '@wordpress/blocks';
import ServerSideRender from '@wordpress/server-side-render';
import { useBlockProps } from '@wordpress/block-editor';

registerBlockType( 'gutenberg-examples/example-dynamic', {
	apiVersion: 3,
	title: 'Example: last post',
	icon: 'megaphone',
	category: 'widgets',

	edit: function ( props ) {
		const blockProps = useBlockProps();
		return (
			<div { ...blockProps }>
				<ServerSideRender
					block="gutenberg-examples/example-dynamic"
					attributes={ props.attributes }
				/>
			</div>
		);
	},
} );

注意: このコードは wp-server-side-render パッケージを使用し、wp-data を使用しません。PHP コード内の依存性を更新してください。自動で依存をビルドするには wp-scripts を使用してください (PHP コード設定については block-development-examples リポジトリーを参照してください)。

原文

最終更新日: