WordPress6.5で実装されたInteractivity APIを試す

参考にした記事

導入

pluginsフォルダにInteractivity APIプラグインのテンプレをコピー。以下のコマンドを実行。

npx @wordpress/create-block@latest [自分のプラグイン名] --template @wordpress/create-block-interactive-template

実行後、自分の場合は以下のメッセージが出て、プラグインのファイル一式はコピーされていなかった。

npx: 126個のパッケージを10.398秒でインストールしました。
Unexpected token .
(node:16351) ExperimentalWarning: The fs.promises API is experimental

他のフォルダで試すと、どうやらnodeのバージョンが古いというエラーが出てるっぽい。

Minimum system requirements not met!

Error: Wanted node version >=20.10.0 (>=20.10.0)
Error: Wanted npm version >=10.2.3 (>=10.2.3)

The program may not complete correctly if you continue.

ローカルのWordPressのpluginsフォルダに適用されるnodeのバージョンが古すぎてエラーメッセージさえでなかったのではと思い、やはりnodeのバージョンが低いのが原因だろうと解釈してnodeのバージョンを最新に上げて実行すると正しく実行されて正常終了した。

まずはテンプレのソースの確認

管理画面からこのプラグインを有効化して、置いてみた。

ターミナルでnpm startして、ソースを弄ってみる。

src/style.scssを適当に変更

.wp-block-create-block-simple-counter {
	font-size: 1em;
	background: #00FF001a;//この行変更
	padding: 1em;
}

src/edit.jsを適当に変更

export default function Edit( { attributes, setAttributes } ) {
	const blockProps = useBlockProps();

	return (
		<p { ...blockProps }>
			{ __(
				'Simple Counter – こんにちは edit.jsを変更したよ',//この行変更
				'simple-counter'
			) }
		</p>
	);
}

保存するとビルドが走り、ちゃんと変更された。

保存して、公開画面で確認してみる。

toggleボタンが表示されていて、クリックすると開く。管理画面側の表示はedit.js、公開側の表示は別のソースに書かれているってこと?ってことで探すと、どうやらrender.phpに書かれてるぽい。

<?php
$unique_id = wp_unique_id( 'p-' );
?>

<div
	<?php echo get_block_wrapper_attributes(); ?>
	data-wp-interactive="create-block"
	<?php echo wp_interactivity_data_wp_context( array( 'isOpen' => false ) ); ?>
	data-wp-watch="callbacks.logIsOpen"
>
	<button
		data-wp-on--click="actions.toggle"
		data-wp-bind--aria-expanded="context.isOpen"
		aria-controls="<?php echo esc_attr( $unique_id ); ?>"
	>
		<?php esc_html_e( 'Toggle', 'simple-counter' ); ?>
	</button>

	<p
		id="<?php echo esc_attr( $unique_id ); ?>"
		data-wp-bind--hidden="!context.isOpen"
	>
		<?php
			esc_html_e( 'Simple Counter - hello from an interactive block!', 'simple-counter' );
		?>
	</p>
</div>

何が何と言うファイル名、などの設定はblock.jsonに書くみたい。

{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 3,
	"name": "create-block/simple-counter",
	"version": "0.1.0",
	"title": "Simple Counter",
	"category": "widgets",
	"icon": "media-interactive",
	"description": "An interactive block with the Interactivity API",
	"example": {},
	"supports": {
		"interactivity": true
	},
	"textdomain": "simple-counter",
	"editorScript": "file:./index.js",
	"editorStyle": "file:./index.css",
	"style": "file:./style-index.css",
	"render": "file:./render.php",//ここで指定
	"viewScriptModule": "file:./view.js"
}

npxで落としてきたテンプレートだとedit.jsとrender.phpの内容が異なり、編集画面ではプレビューとしてテキストだけ表示するような仕様になっているみたい?

参考にしたページでは「ほぼ同じ」内容を書くとのことなのでこれは作り方の問題で、同じでも違ってもいいのかも。

そしてインタラクティブな動きはblock.jsonのviewScriptModuleに設定したjsファイル(この例ではView.js)に書くみたい。たぶんこれがキモの部分。

import { store, getContext } from '@wordpress/interactivity';

store( 'create-block', {
	actions: {
		toggle: () => {
			const context = getContext();
			context.isOpen = ! context.isOpen;
		},
	},
	callbacks: {
		logIsOpen: () => {
			const { isOpen } = getContext();
			// Log the value of `isOpen` each time it changes.
			console.log( `Is open: ${ isOpen }` );
		},
	},
} );

View.jsで指定した属性名create-blockをrender.phpのdata-wp-interactive属性で指定する。

store( 'create-block', {
<div
	<?php echo get_block_wrapper_attributes(); ?>
	data-wp-interactive="create-block"
	<?php echo wp_interactivity_data_wp_context( array( 'isOpen' => false ) ); ?>
	data-wp-watch="callbacks.logIsOpen"
>

色々と書いてるのでわかりづらいけど、要はView.jsで指定した属性名をrender.phpでdata-wp-interactiveというカスタム属性としてもたせればよい、という話だと思う。

ではサンプルに従い何か作って見る

一旦ここまで 続く