【WordPress】PHPだけでカスタムブロックを作れる新機能を試してみた

【WordPress】PHPだけでカスタムブロックを作れる新機能を試してみた

WordPress 7.0でPHPだけでカスタムブロックを作れる機能が追加されました!(PHP-only block registration)

これまではカスタムブロックを作るとなると、JavaScriptやReactの知識が必要になることが多かったのですが、シンプルなブロックならPHPだけでも作れるようになっています!

実際に触ってみると、「ちょっとした定型ブロックなら便利そう!」と思いましたが、画像をメディアライブラリから選ぶようなUIはまだ難しそうで…

「PHPでカスタムブロックを作るか…?非同期パターンでいいのでは?」みたいな葛藤が起きそうな予感がしていますが、できることは多いほうが選択肢が増えて嬉しいので覚えておいて損はないかなと思っています!

早速ブロックを作ってみる

今回は、ひとまずセミナーや説明会のお知らせ記事で使う「セミナー・説明会情報」ブロックを作ってみようと思います。

ブロックで設定できるようにした項目はこちら▼

  • チラシ画像
  • 開催日
  • 申込み期間
  • お問い合わせフォームURL

定型だけど、ちょこちょこ入力内容が変わるようなブロックです

(コアブロックの組み合わせ&非同期パターンで十分なような気もしますが、サンプルなのでご勘弁を…)

参考情報▼

Developers can now create simple blocks using only PHP. This is meant for blocks…
make.wordpress.org

サンプルコードは諸々説明のに掲載しています。

PHPだけでカスタムブロックを作ってみた!

必要なコードを書いて、早速ブロックを追加してみましょう!

ブロックの一覧に表示されました!

本文に追加するとこんな感じ▼

CSSの読み込みもきちんとできていれば編集画面上での見た目もいい感じです!
(CSSは長くなってしまったので今回のサンプルコードからは割愛しています)

設定欄も表示されました!

ただ、画像についてはメディアライブラリから選ぶコントロールはできなさそなので、メディアにアップロードしてURLをコピーして貼り付け方式になりました…これはちょっと実運用ではイマイチですね…

設定をそれぞれ入力して…

公開ページを確認すると…

いい感じですね!見た目もキレイな定型フォーマットになりました!

PHPだけで作るカスタムブロックの「いいな」と思ったとこ・「まだかな」と思ったとこ

「いいな」と思ったとこ

カスタムブロックの開発環境を用意しなくても簡単にオリジナルブロックを作れるのはいいですね!

「ほんのちょっとなんだけど、カスタムブロックにしておきたい」とか「予算的にReactで作るほどの余裕は無いけど、カスタムブロックを作りたい」とかに合いそうです…!

「まだかな」と思ったとこ

設定項目の対応範囲はstringnumberintegerbooleanが中心になっているようなので、「画像をメディアライブラリから選ぶ」みたいなコントロールはまだできなそう(?)でした

なので、かなりシンプルな設定のブロックしか今のところは作れないかもです…

うーん…これだと同期/非同期パターンを組み合わせたほうがいいかもなぁみたいな気もしています…

サンプルコードをさらっと触って作ってみた状態なので、もし追加情報があれば追記します!

今回のサンプルコード

ブロック登録・設定項目定義

function my_register_seminar_info_block() {
	wp_register_style(
		'my-seminar-info-block',
		plugins_url( 'seminar-info-block.css', __FILE__ ), // プラグインとして作る前提。テーマに組み込む場合は get_template_directory_uri() などを使ってください。
		array()
	);
	register_block_type(
		'my/seminar-info',
		array(
			'title'           => __( 'セミナー・説明会情報', 'my-seminar-info' ),
			'description'     => __( 'チラシ画像、開催日、申込み期間、お問い合わせフォームURLを表示します。', 'my-seminar-info' ),
			'category'        => 'text', // ブロックカテゴリは適宜変更してください
			'icon'            => 'megaphone', // アイコンは適宜変更してください
			'attributes'      => array(
				'flyerUrl'          => array(
					'label'   => __( 'チラシ画像URL', 'my-seminar-info' ),
					'type'    => 'string',
					'default' => '',
				),
				'eventDate'         => array(
					'label'   => __( '開催日', 'my-seminar-info' ),
					'type'    => 'string',
					'default' => '',
				),
				'applicationPeriod' => array(
					'label'   => __( '申込み期間', 'my-seminar-info' ),
					'type'    => 'string',
					'default' => '',
				),
				'contactFormUrl'    => array(
					'label'   => __( 'お問い合わせフォームURL', 'my-seminar-info' ),
					'type'    => 'string',
					'default' => 'https://example.com/contact/',
				),
			),
			'render_callback' => 'my_render_seminar_info_block',
			'style'           => 'my-seminar-info-block',
			'supports'        => array(
				'autoRegister' => true,
			),
		)
	);
}
add_action( 'init', 'my_register_seminar_info_block' );

表示側

function my_render_seminar_info_block( $attributes ) {
	$flyer_url          = isset( $attributes['flyerUrl'] ) ? esc_url( $attributes['flyerUrl'] ) : '';
	$event_date         = isset( $attributes['eventDate'] ) ? sanitize_text_field( $attributes['eventDate'] ) : '';
	$application_period = isset( $attributes['applicationPeriod'] ) ? sanitize_text_field( $attributes['applicationPeriod'] ) : '';
	$contact_form_url   = isset( $attributes['contactFormUrl'] ) ? esc_url( $attributes['contactFormUrl'] ) : '';

	if ( '' === $contact_form_url ) {
		$contact_form_url = 'https://example.com/contact/';
	}

	$wrapper_attributes = get_block_wrapper_attributes(
		array(
			'class' => 'my-seminar-info',
		)
	);

	ob_start();
	?>
	<section <?php echo $wrapper_attributes; ?>>
		<?php if ( '' !== $flyer_url ) : ?>
			<figure class="my-seminar-info__flyer">
				<img src="<?php echo esc_url( $flyer_url ); ?>" alt="<?php esc_attr_e( 'セミナー・説明会のチラシ', 'my-seminar-info' ); ?>">
			</figure>
		<?php endif; ?>

		<div class="my-seminar-info__body">
			<p class="my-seminar-info__label"><?php esc_html_e( 'セミナー・説明会情報', 'my-seminar-info' ); ?></p>

			<dl class="my-seminar-info__list">
				<?php if ( '' !== $event_date ) : ?>
					<div class="my-seminar-info__item">
						<dt><?php esc_html_e( '開催日', 'my-seminar-info' ); ?></dt>
						<dd><?php echo esc_html( $event_date ); ?></dd>
					</div>
				<?php endif; ?>

				<?php if ( '' !== $application_period ) : ?>
					<div class="my-seminar-info__item">
						<dt><?php esc_html_e( '申込み期間', 'my-seminar-info' ); ?></dt>
						<dd><?php echo esc_html( $application_period ); ?></dd>
					</div>
				<?php endif; ?>
			</dl>

			<?php if ( '' !== $contact_form_url ) : ?>
				<p class="my-seminar-info__action">
					<a class="my-seminar-info__button" href="<?php echo esc_url( $contact_form_url ); ?>">
						<?php esc_html_e( 'お問い合わせフォームへ', 'my-seminar-info' ); ?>
					</a>
				</p>
			<?php endif; ?>
		</div>
	</section>
	<?php

	return trim( ob_get_clean() );
}