ブロックの静的レンダリングと動的レンダリング

ブロックのフロントエンドのマークアップ生成には2通りの方式があります。リクエストに応じてサーバーサイドで動的に生成する方式 (動的ブロック、ダイナミックブロック)と、ブロックエディターでの save プロセス中に静的に生成する方式 (静的ブロック) です。この記事では、それぞれの方式について説明します。

投稿「Static vs. dynamic blocks: What’s the difference?」は、このトピックに関する素晴らしい入門記事です。

静的レンダリング

「静的レンダリング」を行うブロックは、保存時に、データベース内に保存され固定されるフロントエンド出力を生成します。このブロックは HTML マークアップの定義に関して、 save 関数にのみ依存します。マークアップはブロックエディター内で手動で編集しない限り、変更されません。

ブロックが動的なレンダリング方法を使用しなければ、すなわち、ページが読み込まれたときに PHP を介してその場でコンテンツを生成しなければ、このブロックは「静的ブロック」と見なされます。

次の図は、静的ブロックのコンテンツがどのようにデータベース内に保存され、どのようにフロントエンドで HTML として取得、レンダーされるかを示しています。

図: 静的レンダリングのブロック

Top ↑

ブロックで静的レンダリングを定義する方法

save 関数は、クライアントにブロックを登録する際に定義され、ブロックの HTML 構造を指定します。HTML 構造はエディターでのブロックの保存時にデータベース内に保存され、フロントエンドでのブロックの表示に使用されます。

WordPress のブロックは、固有のブロック区切りとして機能する特別なコメントタグ内にカプセル化されます。ただし、静的ブロックの save 関数で定義された HTML のみがこれらの区切り文字を取り除いてレンダーされます。

Top ↑

整形済みテキストブロックの静的レンダリングの例

コアの整形済みテキストブロックの save 関数は以下のようになります。

import { RichText, useBlockProps } from '@wordpress/block-editor';

export default function save( { attributes } ) {
	const { content } = attributes;

	return (
		<pre { ...useBlockProps.save() }>
			<RichText.Content value={ content } />
		</pre>
	);
}

この関数は、attributes.content の値が "This is some preformatted text" のとき、次のようなブロックのマークアップ表現を生成します:

<!-- wp:preformatted -->
<pre class="wp-block-preformatted">This is some preformatted text</pre>
<!-- /wp:preformatted -->

フロントエンドでこのブロックは、次のようなマークアップを返します。区切りがないことに注意してください。

<pre class="wp-block-preformatted">This is some preformatted text</pre>

次のセクションで説明する動的ブロックは、静的ブロックと同様に save 関数で、最初の HTML 構造を指定できます。しかし、動的ブロックは主にサーバー側のレンダリングに依存してコンテンツを生成します。何らかの理由で動的なレンダリングが利用できない場合、たとえばブロックのプラグインが無効の場合など、システムはデータベースに保存された HTML 構造を使用してフロントエンドにブロックを表示します。

この仕組みの実践的なデモについては、チュートリアルのはじめてのブロック作成を参照してください。特に、静的レンダリングの追加 セクションではブロックが、保存された HTML 構造と動的レンダリング機能の両方を持つ方法を説明しています。

WordPress では render_block や render_callback 関数のようなメカニズムが提供され、フロントエンドに表示される前に保存されたブロックの HTML を変更できます。これらのツールは、ブロックの出力を動的にカスタマイズする機能を開発者に提供し、複雑でインタラクティブなユーザー体験に対応します。

静的レンダリングを使用する例、すなわち、出力が保存時に固定され、サーバーサイドでの処理に依存しない WordPress ブロックの例には、他にも以下があります。

Top ↑

動的レンダリング

「動的レンダリング」を行うブロックは、フロントエンド側で要求された際に、リアルタイムでコンテンツと構造を生成するように設計されています。データベースに保存された固定した HTML 構造を持つ静的ブロックとは異なり、「動的ブロック」はサーバーサイドの処理に依存して動的に出力を構築するため、汎用性が高く、頻繁に更新する必要があるコンテンツや外部データに依存するコンテンツに適しています。

次の図は、どのように動的ブロックの表現が保存され、フロントエンドで HTML として取得され、動的にレンダーされるかを示しています。

図: 動的レンダリングのブロック

動的ブロックの一般的な使用例を挙げます。

  1. 投稿が更新されていなくても、コンテンツが変更されるべきブロック: このブロックの例は最新の投稿ブロックです。新しい投稿が公開されると自動的に更新されます。
  1. マークアップの更新が即座にフロントエンドに表示されるべきブロック: 新しいクラスや HTML 要素の追加、その他の方法によるレイアウトの変更などでブロックの構造を変更する場合、動的ブロックを使用すると、サイト全体でのブロックの利用箇所のすべてで即座に変更を適用できます。動的ブロックでなければ、同様の更新はブロックエディター内でバリデーションエラーを引き起こします。

Top ↑

ブロックで動的レンダリングを使用する方法

ブロックは主に2つの方法で動的レンダリングを定義できます。

  1. register_block_type() 関数に渡す render_callback 引数を使用する。
  1. 通常 render.php という名前の個別の PHP ファイルを使用する。このファイルのパスは block.json ファイルの render プロパティを使用して定義します。

どちらの方法も次のデータを受け取ります。

  • $attributes: ブロックの属性の配列
  • $content: データベース内に保存される、ブロックのマークアップ (もしあれば)
  • $blockWP_Block クラスのインスタンス。レンダーされるブロックを表す (ブロックのメタデータ)。

Top ↑

サイトのタイトルブロックの動的レンダリングの例

サイトのタイトルブロックは以下のrender_callback を使用します。

function render_block_core_site_title( $attributes ) {
	$site_title = get_bloginfo( 'name' );
	if ( ! $site_title ) {
		return;
	}

	$tag_name = 'h1';
	$classes  = empty( $attributes['textAlign'] ) ? '' : "has-text-align-{$attributes['textAlign']}";
	if ( isset( $attributes['style']['elements']['link']['color']['text'] ) ) {
		$classes .= ' has-link-color';
	}

	if ( isset( $attributes['level'] ) ) {
		$tag_name = 0 === $attributes['level'] ? 'p' : 'h' . (int) $attributes['level'];
	}

	if ( $attributes['isLink'] ) {
		$aria_current = is_home() || ( is_front_page() && 'page' === get_option( 'show_on_front' ) ) ? ' aria-current="page"' : '';
		$link_target  = ! empty( $attributes['linkTarget'] ) ? $attributes['linkTarget'] : '_self';

		$site_title = sprintf(
			'<a href="%1$s" target="%2$s" rel="home"%3$s>%4$s</a>',
			esc_url( home_url() ),
			esc_attr( $link_target ),
			$aria_current,
			esc_html( $site_title )
		);
	}
	$wrapper_attributes = get_block_wrapper_attributes( array( 'class' => trim( $classes ) ) );

	return sprintf(
		'<%1$s %2$s>%3$s</%1$s>',
		$tag_name,
		$wrapper_attributes,
		// already pre-escaped if it is a link.
		$attributes['isLink'] ? $site_title : esc_html( $site_title )
	);
}

しかし、index.js ファイルを見ればわかるように、このブロックには save 関数が定義されていません。したがってデータベース内のブロックのマークアップ表現は次のようになります。

<!-- wp:site-title /-->

フロントエンドでは、render_callbackを使用して、ブロックがリクエストされた時点でのサーバ上の特定の値に応じて、ブロックのマークアップが動的にレンダーされます。値には、現在のサイトのタイトル、URL、リンク先などが含まれます。

<h1 class="wp-block-site-title"><a href="https://www.wp.org" target="_self" rel="home">My WordPress Website</a></h1>

Top ↑

データベース内の動的ブロックの HTML 表現 (save)

動的ブロックの saveコールバック関数は nullのみを返して、エディターに対し、既存のブロック属性と一緒にブロックの区切りコメントだけをデータベースに保存するように指示できます。これらの属性はサーバーサイドのレンダリングコールバックに渡され、サイトのフロントエンドでどのようにブロックを表示するかを決定します。

save が null の場合、ブロックエディターは ブロックマークアップの検証プロセス をスキップし、頻繁なマークアップの変更で引き起こされる問題を回避します。

動的レンダリングを持つブロックはまた、ブロックの HTML 表現をバックアップとして保存できます。サーバサイドレンダリングのコールバックを提供した場合、データベース内のブロックを表す HTML はコールバックの出力に置き換えられますが、ブロックを登録したプラグインをアンインストールするなどしてブロックが無効化されたり、レンダーコールバックが削除されると、HTML はレンダーされます。

場合によってはブロックはブロックの HTML 表現を保存し、いくつかの条件が満たされた場合にこのマークアップを微調整するために、動的レンダリングを使用します。この方法を使用したコアブロックの例をいくつか挙げます。

  • カバーブロックは、データベース内にブロックの完全な HTML 表現を保存します。このマークアップは render_callback を介して処理され、「アイキャッチ画像を使用する」設定が有効な場合には、アイキャッチ画像が動的に挿入されます。
  • 画像ブロックもまたその HTML 表現をデータベース内に保存します。このマークアップは render_callback を介して処理され、特定の条件を満たす場合は、マークアップに属性を追加します。

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

Top ↑

その他の情報

原文

最終更新日: