GutenbergがWordPressの標準エディターとなった今、ウェブデザインの可能性は、WordPressテーマに縛られません。WordPressには、優れたサイトのレイアウトに必要なデザインツールが搭載されており、テーマはサイトの構築やデザイン機能を強化する目的で使用することができます。

そしてブロックテンプレートは、サイト構築をさらに強化してくれる存在。ブロックエディターハンドブックには、以下のように記載されています。

ブロックテンプレートはブロックアイテムのリストとして定義されます。定義済みの属性やプレースホルダーコンテンツを含めることができ、静的にも動的にもできます。ブロックテンプレートを使用して、エディターセッションのデフォルトの初期状態を指定できます。

言い換えるなら、ブロックテンプレートは、デフォルト状態をクライアント上で動的に設定するために使用可能な複数のブロックアイテムの一覧です。

👉 ブロックテンプレートとテンプレートファイルの違い

テンプレートファイルは、index.phppage.phpsingle.phpなどのPHPファイルで、WordPressのテンプレート階層に応じて、クラシックテーマでもブロックテーマでも同じように動作します。クラシックテーマでは、これらのファイルはPHPとHTMLで書かれており、ブロックテーマではすべてブロックで構成されています。

👉 ブロックテンプレートとブロックパターンの違い

ブロックパターンは自分でページに追加する必要がありますが、ブロックテンプレートは、新規投稿を作成する際に自動で読み込まれます。

また、特定のブロックテンプレートをカスタム投稿タイプに設定したり、デフォルトで一部のブロックや機能をロックしてエラーを防止したりすることも。

ブロックテンプレートを作成する方法は2通りあり、ブロックAPIを使用してPHPでブロックタイプの配列を宣言するか、InnerBlocksコンポーネントを使用して作成します。

PHPを使ってブロックテンプレートを作成する方法

従来の方法としては、プラグインやテーマのfunctions.phpを使用して、独自のブロックテンプレートを定義します。プラグインを使う場合は、任意のコードエディターを開いて新規PHPファイルを作成し、以下のコードを貼り付けてください。

<?php
/*
 * Plugin Name:       My Block Templates
 * Plugin URI:        https://example.com/
 * Description:       An example plugin
 * Version:           1.0
 * Requires at least: 5.5
 * Requires PHP:      8.0
 * Author:            Your name
 * Author URI:        https://author.example.com/
 * License:           GPL v2 or later
 * License URI:       https://www.gnu.org/licenses/gpl-2.0.html
 * Update URI:        https://example.com/my-plugin/
 */

function myplugin_register_my_block_template() {
	$post_type_object = get_post_type_object( 'post' );
	$post_type_object->template = array(
		array( 'core/image' ),
		array( 'core/heading' ),
		array( 'core/paragraph' )
	);
}
add_action( 'init', 'myplugin_register_my_block_template' );

上のコードでは、get_post_type_objectが名前で投稿タイプを取得します。

ファイルをwp-content/pluginsフォルダに保存したら、WordPress管理画面の「プラグイン」画面に移動して、My Block Templatesプラグインを有効化してください。

新規投稿を作成すると、エディターに画像ブロック、見出し、段落を含むブロックテンプレートが表示されるようになります。

投稿エディターで自動的に読み込まれるブロックテンプレート
投稿エディターで自動的に読み込まれるブロックテンプレート

ブロックごとに設定を追加したり、ブロックの入れ子構造を作成することも可能です。以下は、内部ブロックと設定を含むより高度なブロックテンプレートを構築するコード例です。

function myplugin_register_my_block_template() {

	$block_template = array(
		array( 'core/image' ),
		array( 'core/heading', array(
			'placeholder'	=> 'Add H2...',
			'level'			=> 2
		) ),
		array( 'core/paragraph', array(
			'placeholder'	=> 'Add paragraph...'
			
		) ),
		array( 'core/columns', 
			array(), 
			array( 
				array( 'core/column',
					array(),
					array(
						array( 'core/image' )
					)
				), 
				array( 'core/column',
					array(),
					array(
						array( 'core/heading', array(
							'placeholder'	=> 'Add H3...',
							'level'			=> 3
						) ),
						array( 'core/paragraph', array(
							'placeholder'	=> 'Add paragraph...'
						) )
					) 
				)
			) 
		)
	);
	$post_type_object = get_post_type_object( 'post' );
	$post_type_object->template = $block_template;
}
add_action( 'init', 'myplugin_register_my_block_template' );

このコードを実行すると、以下のようになります。

より高度なブロックテンプレート
より高度なブロックテンプレート

ここまではコアブロックのみ。以下のように、ブロックテンプレートにカスタムブロックブロックパターンを加えることもできます。

function myplugin_register_my_block_template() {
	$post_type_object = get_post_type_object( 'page' );
	$post_type_object->template = array(
		array( 'core/pattern', array(
			'slug' => 'my-plugin/my-block-pattern'
		) ) 
	);
}
add_action( 'init', 'myplugin_register_my_block_template' );

既存のカスタム投稿タイプ用のデフォルトブロックテンプレートを作成する場合も、ほぼ同様の手順になります。以下のように、get_post_type_objectの投稿タイプを置き換えるだけでOKです。

<?php
function myplugin_register_my_block_template() {
	$post_type_object = get_post_type_object( 'book' );
	$post_type_object->template = array(
		array( 'core/image' ),
		array( 'core/heading' ),
		array( 'core/paragraph' )
	);
}
add_action( 'init', 'myplugin_register_my_block_template' );

ブロックテンプレートの作成方法を押さえたところで、より具体的な使用例を見ていきましょう。

カスタム投稿タイプのブロックテンプレート

前述したとおり、カスタム投稿タイプで使用するブロックテンプレートを作成することができます。すでに作成済みのカスタム投稿タイプに後から設定することも可能ですが、カスタム投稿タイプの作成時に一緒に定義するのがおすすめです。

この場合、templatetemplate_lock引数のregister_post_type関数を使用します。

function myplugin_register_book_post_type() {
	$args = array(
		'label' => esc_html__( 'Books' ),
		'labels' => array(
			'name' => esc_html__( 'Books' ),
			'singular_name' => esc_html__( 'Book' ),
		),
		'public' => true,
		'publicly_queryable' => true,
		'show_ui' => true,
		'show_in_rest' => true,
		'rest_namespace' => 'wp/v2',
		'has_archive' => true,
		'show_in_menu' => true,
		'show_in_nav_menus' => true,
		'supports' => array( 'title', 'editor', 'thumbnail' ),
		'template' => array(
			array( 'core/paragraph', array(
				'placeholder'	=> 'Add paragraph...'
			) ),
			array( 'core/columns', 
				array(), 
				array( 
					array( 'core/column',
						array(),
						array(
							array( 'core/image' )
						)
					), 
					array( 'core/column',
						array(),
						array(
							array( 'core/heading', array(
								'placeholder'	=> 'Add H3...',
								'level'			=> 3
							) ),
							array( 'core/paragraph', array(
								'placeholder'	=> 'Add paragraph...'
							) )
						) 
					)
				)
			)
		)
	);
	register_post_type( 'book', $args );
}
add_action( 'init', 'myplugin_register_book_post_type' );

以上で完了です。以下は、エディターに表示されるカスタム投稿タイプ「Book」のブロックテンプレート例です。

カスタム投稿タイプのブロックテンプレート
カスタム投稿タイプのブロックテンプレート

レイアウトが完成したら、ブロック設定で動作や見た目を微調整していきましょう。

ブロック属性でブロックテンプレートを微調整する方法

ブロックテンプレートをブロックのリストとして定義したら、リストの各項目にブロック名と任意の属性の配列が必要です。入れ子になった配列では、子ブロック用に3つ目の配列を追加することも可能です。

Columnsブロックを持つテンプレートは以下のようになります。

$template = array( 'core/columns', 
	// attributes
	array(), 
	// nested blocks
	array(
		array( 'core/column' ),
		array( 'core/column' ) 
	) 
);

2行目はブロック属性(任意)の配列です。この属性でによって、ページのレイアウトやデザインを気にせずコンテンツの執筆に集中できるよう、テンプレートの外観をカスタマイズすることができます。

手始めに、ブロックエディターを使って、テンプレートの基盤となるブロック構造を作成しましょう。

ブロックエディターのブロックレイアウト
ブロックエディターのブロックレイアウト

ブロックを追加し、レイアウトとスタイルを編集してから、コードエディターに切り替えてブロックデリミタを見つけます。

Columnsブロックのブロックデリミタ
Columnsブロックのブロックデリミタ

ブロックデリミタは、ブロックの設定とスタイルをキーと値のペアで保存します。ブロックマークアップからキーと値をコピー&ペーストするだけで、属性の配列に追加することができます。

$template = array( 'core/columns', 
	array(
		'verticalAlignment'	=> 'center',
		'align'				=> 'wide',
		'style'				=> array( 
			'border'	=> array(
				'width'	=> '2px',
				'radius'	=> array(
					'topLeft'		=> '12px', 
					'topRight'		=> '12px', 
					'bottomLeft'	=> '12px', 
					'bottomRight'	=> '12px'
				)
			)
		),
		'backgroundColor' => 'tertiary'
	),
	array(
		array( 'core/column' ),
		array( 'core/column' ) 
	) 
);

テンプレート内の各ブロックで同じ作業を繰り返し行えば完了です。

$template = array(
	array( 'core/paragraph', array(
		'placeholder'	=> 'Add paragraph...'
	) ),
	array( 'core/columns', 
		array(
			'verticalAlignment'	=> 'center',
			'align'				=> 'wide',
			'style'				=> array( 
				'border'	=> array(
					'width'		=> '2px',
					'radius'	=> array(
						'topLeft'		=> '12px', 
						'topRight'		=> '12px', 
						'bottomLeft'	=> '12px', 
						'bottomRight'	=> '12px'
					)
				)
			),
			'backgroundColor' => 'tertiary',
			'lock' => array(
				'remove'	=> true,
				'move'		=> true
			)
		), 
		array( 
			array( 'core/column',
				array( 'verticalAlignment'	=> 'center' ),
				array(
					array( 'core/image', 
						array(
							'style'	=> array( 'border' => array( 'radius' => '8px' ) ) 
						) 
					)
				)
			), 
			array( 'core/column',
				array( 'verticalAlignment'	=> 'center' ),
				array(
					array( 'core/heading', array(
						'placeholder'	=> 'Add H3...',
						'level'			=> 3
					) ),
					array( 'core/paragraph', array(
						'placeholder'	=> 'Add paragraph...'
					) )
				) 
			)
		)
	)
);

ブロックのロック

$post_type_objecttemplate_lockプロパティを使って、特定のブロックまたはテンプレートに含まれるすべてのブロックをロックすることができます。

たとえば投稿者が複数いるブログサイトで、全員または特定のユーザーがブロックテンプレートのレイアウトを変更できないように設定するのに非常に便利です。

以下は、ブロックテンプレート内のすべてのブロックをロックするコード例です。

function myplugin_register_my_block_template() {
	$post_type_object = get_post_type_object( 'post' );
	$post_type_object->template = array(
		array( 'core/image' ),
		array( 'core/heading' ),
		array( 'core/paragraph' )
	);
	$post_type_object->template_lock = 'all';
}
add_action( 'init', 'myplugin_register_my_block_template' );

ロックされたブロックは、以下のようにブロックツールバーとリストビューで鍵のアイコンが表示されます。

ロックされた見出しブロック
ロックされた見出しブロック

ブロックのロックは、ブロックツールバーのオプションメニューで解除可能です。

ブロックのロックを解除
ブロックのロックを解除

ロック解除」をクリックすると、モーダルポップアップが表示され、移動の有効・無効化、削除を防止、またはその両方を設定することができます。

ロック設定
ロック設定

template_lockは、以下のいずれかの値を取ります。

  • all─新規ブロックの追加、既存ブロックの移動や削除を防止
  • insert─新規ブロックの追加、既存ブロックの削除を防止
  • contentOnly─テンプレートに含まれるブロックの内容のみ編集。contentOnlyは、パターンまたはテンプレート単位でのみ使用でき、コードでの管理が必要(APIのロックについてはこちら)。
template_lockを設定してテンプレートブロックの削除を防止
template_lockを設定してテンプレートブロックの削除を防止

特定のブロックをロックするには、各ブロックにlockを追加します。

function myplugin_register_my_block_template() {
	$post_type_object = get_post_type_object( 'post' );
	$post_type_object->template = array(
		array( 'core/image' ),
		array( 'core/heading' ),
		array( 'core/paragraph', array(
			'lock' => array(
				'remove'	=> true,
				'move'		=> true
			)
		) )
	);
}
add_action( 'init', 'myplugin_register_my_block_template' );

lock属性は以下のいずれかの値を取ります。

  • remove─ブロックの削除を防止
  • move─ブロックの移動を防止

また、locktemplate_lockを併用することで、ブロックテンプレートのブロックの動作を微調整することができます。以下は、見出し以外のブロックをすべてロックする例です。

function myplugin_register_my_block_template() {
	$post_type_object = get_post_type_object( 'post' );
	$post_type_object->template = array(
		array( 'core/image' ),
		array( 'core/heading', array(
			'lock' => array(
				'remove'	=> false,
				'move'		=> false
			) 
		) ),
		array( 'core/paragraph' )
	);
	$post_type_object->template_lock = 'all';
}
add_action( 'init', 'myplugin_register_my_block_template' );

すると、以下のように見出しブロックのロックが解除されます。

ロックされたブロックとロックが解除されたブロック
ロックされたブロックとロックが解除されたブロック

ブロック開発者は、attributesレベルのブロック定義でlock属性を使用することも可能です(ブロックを個別にロックする方法はこちら)。

ブロックのロックを解除できないようにする方法

ここまでにご紹介したコードを実際にテストすると、エディターのインターフェースからブロックのロックを解除できることにお気づきでしょう。デフォルトでは、編集権限を持つすべてのユーザーがブロックをロックまたはロック解除することができます。

ブロックをロックするかロック解除するかは、block_editor_settings_allフィルターを使用して制御することができます。

フィルターは、初期化されたエディターにあらゆる設定を送信します。つまり、初期化時にエディターの設定に使用されるあらゆる設定は、送信前にPHP WordPressプラグインによってフィルタリングされることがあります。(英語原文の日本語訳)

このフィルターで使用するコールバック関数は、以下2つのパラメータを受け取ります。

  • $settings─エディター設定の配列
  • $contextWP_Block_Editor_Contextクラスのインスタンスでレンダリング中のブロックエディターに関する情報を含むオブジェクト

以下のように$settings['canLockBlocks']をフィルタリングし、trueまたはfalseを設定します。

add_filter( 'block_editor_settings_all', 
	function( $settings, $context ) {
		if ( $context->post && 'book' === $context->post->post_type ) {
			$settings['canLockBlocks'] = false;
		}
		return $settings;
	}, 10, 2
);

現在のユーザー権限を条件付きで確認することで、特定のユーザー権限からブロックのロック、ロック解除を除外することができます。

以下は、現在作業しているユーザーが他のユーザーの投稿を編集できるかどうか(現在作業しているユーザーの権限が「編集者」以上かどうか)をチェックする例です。

add_filter( 'block_editor_settings_all', 
	function( $settings, $context ) {
		if ( $context->post && 'book' === $context->post->post_type ) {
			$settings['canLockBlocks'] = current_user_can( 'edit_others_posts' );
		}
		return $settings;
	}, 10, 2
);

管理者と投稿者のデフォルトのエディターの外観を比較してみましょう。以下は管理者のエディターです。

管理者に表示されるエディターの外観
管理者に表示されるエディターの外観

投稿者には以下のように表示されます。

投稿者に表示されるエディターの外観
投稿者に表示されるエディターの外観

また、現在作業しているユーザーに関するあらゆる条件を確認することができます。以下のコードは、特定ユーザーがブロックをロック/ロック解除できないようにするものです。

add_filter( 'block_editor_settings_all', 
	function( $settings, $context ) {
		$user = wp_get_current_user();
		if ( in_array( $user->user_email, [ '[email protected]' ], true ) ) {
			$settings['canLockBlocks'] = false;
		}
		return $settings;
	}, 10, 2
);

さらに条件を組み合わせれば、テンプレート内のブロックのロック/ロック解除を許可するユーザーと許可しないユーザーをきめ細かく管理することができます。

しかし実は、コードエディターを使用すれば、UIでブロックのロック/ロック解除の権限を持たないユーザーでもコンテンツを変更することができます。

特定のユーザー権限でコードエディターの使用を許可しない方法

デフォルトでは、コンテンツを編集できるすべてのユーザーがコードエディターにアクセスできるようになっています。そのため、ロック設定が上書きされ、テンプレートレイアウトが壊れたり、削除されたりする可能性があります。

block_editor_settings_allを使用して、codeEditingEnabled設定をフィルタリングし、特定のユーザー権限でコードエディターの使用を制限することもできます。コード例は以下の通り。

add_filter( 'block_editor_settings_all', 
	function( $settings, $context ) {
		if ( $context->post && 'book' === $context->post->post_type ) {
			$settings['canLockBlocks'] = current_user_can( 'edit_others_posts' );
			$settings['codeEditingEnabled'] = current_user_can( 'edit_others_posts' );
		}
		return $settings;
	}, 10, 2
);

このコードを加えると、edit_others_postsの権限を持たないユーザーはコードエディターにアクセスできなくなります。投稿者に表示されるオプションツールバーは、以下のようになります。

コードエディターにアクセス権限を持たないユーザーに表示されるのオプションツールバー
コードエディターにアクセス権限を持たないユーザーに表示されるのオプションツールバー

以上が、PHPでブロックテンプレートを作成するために必要な知識です。Gutenbergブロック開発を行なっていて、JavaScriptを使用したい場合には、次のご紹介する方法を選択してください。

JavaScriptを使ってテンプレートを構築する方法

JavaScriptを使って投稿にブロックテンプレートを追加する場合は、手順が異なります。テンプレートを作成することはできますが、Gutenbergブロック開発の解説記事でご説明している通り、カスタムブロックを作成して、InnerBlocksコンポーネントを使用しなければなりません。

InnerBlocksは、コンポーネントのペアをエクスポートし、ネストしたブロックコンテンツを実現するブロックを実装するもの。(英語原文の日本語訳)

では、この手順を見ていきましょう。

他のGutenbergコンポーネント同様、カスタムブロックでInnerBlocksを使用することができます。

まずは、他の依存関係と一緒にパッケージからInnerBlocksを取り込みます。

import { registerBlockType } from '@wordpress/blocks';
import { useBlockProps, InnerBlocks } from '@wordpress/block-editor';

次に、InnerBlocksのプロパティを定義します。以下は、TEMPLATE定数を宣言し、InnerBlocksコンポーネントのtemplateプロパティの値を設定する例です。

const TEMPLATE = [
	[ 'core/paragraph', { 'placeholder': 'Add paragraph...' } ],
	[ 'core/columns', { verticalAlignment: 'center' }, 
		[
			[ 
				'core/column', 
				{ templateLock: 'all' }, 
				[
					[ 'core/image' ]
				]
			],
			[ 
				'core/column', 
				{ templateLock: 'all' }, 
				[
					[ 
						'core/heading', 
						{'placeholder': 'Add H3...', 'level': 3}
					], 
					[ 
						'core/paragraph', 
						{'placeholder': 'Add paragraph...'} 
					]
				], 
			]
		]
	]
];
registerBlockType( metadata.name, {
	title: 'My Template',
	category: 'widgets',
	edit: ( props ) => {
		return(
			<div>
				<InnerBlocks
					template={ TEMPLATE }
					templateLock="insert"
				/>
			</div>
		)
	},
	save() {
		const blockProps = useBlockProps.save();
		return(
			<div { ...blockProps }>
				<InnerBlocks.Content />
			</div>
		)
	}
} );

上のコードは非常にシンプルです。templateLock属性が2回使用されていることがわかります(ブロックレベルとInnerBlocksコンポーネント内)。利用可能なpropsについては、InnerBlocks に関するドキュメントまたはブロックエディターハンドブックを参照してください。

それでは、作業を進めていきましょう。

まずは、DevKinstaのようなローカル開発環境にWordPressをインストールします。

コマンドラインツールを起動して、pluginsフォルダに移動し、以下のコマンドを実行してください。

npx @wordpress/create-block template-block

ブロック名はお好きな名前に変更可能です。スターターブロックを詳細に管理したい場合は、Gutenbergブロック開発の解説記事の手順を参照してください。

インストールが完了したら、以下のコマンドを実行します。

cd template-block
npm start

WordPressの管理画面を開き、「プラグイン」画面に移動して、Template Blockプラグインを見つけて有効化しましょう。

任意のコードエディターで、srcフォルダの下にあるindex.jsファイルを開きます。上のコードをコピー&ペーストしてindex.jsを保存し、WordPressの管理画面に戻り、投稿または固定ページを新規作成します。

ブロックインサーターを開いて、「ウィジェット」セクションまでスクロールすると、カスタムブロックが見つかります。

ブロックインサーターのカスタムブロック
ブロックインサーターのカスタムブロック

投稿に追加して、コンテンツを編集したら投稿を保存しましょう。

カスタムテンプレートの一覧
カスタムテンプレートの一覧

コードエディターに切り替えると、次のようなマークアップが表示されます。

<!-- wp:create-block/template-block -->
<div class="wp-block-create-block-template-block"><!-- wp:paragraph {"placeholder":"Add paragraph..."} -->
<p></p>
<!-- /wp:paragraph -->

<!-- wp:columns {"verticalAlignment":"center"} -->
<div class="wp-block-columns are-vertically-aligned-center"><!-- wp:column {"templateLock":"all"} -->
<div class="wp-block-column"><!-- wp:image -->
<figure class="wp-block-image"><img alt=""/></figure>
<!-- /wp:image --></div>
<!-- /wp:column -->

<!-- wp:column {"templateLock":"all"} -->
<div class="wp-block-column"><!-- wp:heading {"level":3,"placeholder":"Add H3..."} -->
<h3 class="wp-block-heading"></h3>
<!-- /wp:heading -->

<!-- wp:paragraph {"placeholder":"Add paragraph..."} -->
<p></p>
<!-- /wp:paragraph --></div>
<!-- /wp:column --></div>
<!-- /wp:columns --></div>
<!-- /wp:create-block/template-block -->

任意のブラウザでプレビューを見てみましょう。ブロックの外観を編集するには、style.scssファイルのスタイルを変更するだけでOKです。

カスタマイズを終えたら、npm run buildを実行してください。buildフォルダにプロジェクトのファイルがすべて圧縮され、利用可能な状態になります。

これで、数回のクリックで高度なブロックテンプレートが作成できるようになりました。

まとめ

投稿やカスタム投稿タイプにブロックテンプレートを追加することで、WordPressサイトの作成と編集体験を劇的に改善、高速化することができます。また、ブロックテンプレートは、複数のユーザー間で同じフォーマットを維持する必要があるマルチユーザーサイトで特に便利です。

新規投稿を作成する際には、自分でブロックパターンを追加することなく、統一されたレイアウトを使用することができるため、レビューサイトやレシピサイトにもうってつけです。

静的または動的なカスタムブロック、ブロックパターン、ブロックテンプレートを組み合わせれば、あらゆるタイプのWordPressサイト構築を最大限効率化することができます。

ブロックテンプレートをすでに使用していますか?どのような用途に役立てていますか?以下のコメント欄でぜひお聞かせください。

Carlo Daniele Kinsta

Carlo is a passionate lover of webdesign and front-end development. He has been playing with WordPress for more than 20 years, also in collaboration with Italian and European universities and educational institutions. He has written hundreds of articles and guides about WordPress, published both on Italian and international websites, as well as on printed magazines. You can find him on LinkedIn.