プラグイン用サイドバー

Topics

  • 概要
  • はじめる前に
  • ステップバイステップガイド
    • ステップ 1: サイドバーの起動
    • ステップ 2: サイドバーのスタイルの調整とコントロールの追加
    • ステップ 3: メタフィールドの登録
    • ステップ 4: 入力コントロールの初期化
    • ステップ 5: 入力コントロールの変更でメタフィールドを更新する
  • 追加リソース
  • まとめ
    • 注意

概要

プラグインにサイドバーを追加する方法を説明します。サイドバーは、エディターの右端にある領域です。プラグインは、InspectorControls(歯車のアイコン)の横に、展開可能なアイコンを追加できます。

サイドバーの例

注意: このチュートリアルではカスタムサイドバーを扱います。 サイドバーへのコントロールの追加については、ブロックツールバーと設定サイドバーを参照してください。

Top ↑

はじめる前に

このチュートリアルでは、設定済みのプラグインがあり、PHP と JavaScript のコードを追加できることを前提としています。WordPress プラグインの入門、ブロックエディター拡張プラグインの使用法については JavaScript 入門 チュートリアルを参照してください。

Top ↑

ステップバイステップガイド

Top ↑

ステップ 1: サイドバーの起動

最初のステップではまずエディターに対して新しいプラグインが自身のサイドバーを持つことを伝えます。これには registerPluginPluginSidebarcreateElement ユーティリティを使用します。それぞれ @wordpress/plugins、 @wordpress/edit-postreact パッケージに含まれます。

次のコードを JavaScript ファイル plugin-sidebar.js に追加し、プラグインディレクトリに保存してください。

( function ( wp, React ) {
	var el = React.createElement;
	var registerPlugin = wp.plugins.registerPlugin;
	var PluginSidebar = wp.editPost.PluginSidebar;

	registerPlugin( 'my-plugin-sidebar', {
		render: function () {
			return el(
				PluginSidebar,
				{
					name: 'my-plugin-sidebar',
					icon: 'admin-post',
					title: 'My plugin sidebar',
				},
				'Meta field'
			);
		},
	} );
} )( window.wp, window.React );

このコードが動作するにはブラウザ内でユーティリティが利用可能でなければなりません。スクリプトで、wp-pluginswp-edit-postreact を依存として指定します。

以下はスクリプトを登録し、依存を指定する PHP コードです。

<?php

/*
Plugin Name: Sidebar plugin
*/

function sidebar_plugin_register() {
	wp_register_script(
		'plugin-sidebar-js',
		plugins_url( 'plugin-sidebar.js', __FILE__ ),
		array( 'wp-plugins', 'wp-edit-post', 'react' )
	);
}
add_action( 'init', 'sidebar_plugin_register' );

function sidebar_plugin_script_enqueue() {
	wp_enqueue_script( 'plugin-sidebar-js' );
}
add_action( 'enqueue_block_editor_assets', 'sidebar_plugin_script_enqueue' );

プラグインをインストールし有効化すると、エディターの右上に新しい「ピン」アイコンが表示され、クリックするとプラグインのサイドバーが開きます。

サイドバーの起動

Top ↑

ステップ 2: サイドバーのスタイルの調整とコントロールの追加

サイドバーが起動できたら次のステップとして必要なコンポーネントと基本的なスタイルを追加します。

メタフィールド値の表示や編集には入力コンポーネントを使用します。@wordpress/components パッケージには再利用可能な多くのコンポーネントがあり、特に TextControl は入力フィールドの作成を目的とします。

( function ( wp ) {
	var el = React.createElement;
	var registerPlugin = wp.plugins.registerPlugin;
	var PluginSidebar = wp.editPost.PluginSidebar;
	var TextControl = wp.components.TextControl;

	registerPlugin( 'my-plugin-sidebar', {
		render: function () {
			return el(
				PluginSidebar,
				{
					name: 'my-plugin-sidebar',
					icon: 'admin-post',
					title: 'My plugin sidebar',
				},
				el(
					'div',
					{ className: 'plugin-sidebar-content' },
					el( TextControl, {
						label: 'Meta Block Field',
						value: 'Initial value',
						onChange: function ( content ) {
							console.log( 'content changed to ', content );
						},
					} )
				)
			);
		},
	} );
} )( window.wp );

plugin-sidebar.js をこの新しいコードで更新します。@wordpress/components パッケージの新しいユーティリティ wp.components を使用していることに注意してください。PHP ファイルの wp_register_script 関数の依存に wp-components を追加してください。

コードは以下を導入します。

  • スタイルを適用できるよう、div 要素に CSS クラス plugin-sidebar-content
  • プレーンな 'Meta field' テキストの代わりに TextControl component

新しい CSS クラスを使用して、スタイルを追加できます。プラグインディレクトリに新しいファイル plugin-sidebar.css を作成し、次のパディングを追加するコードを挿入してください。

.plugin-sidebar-content {
	padding: 16px;
}

スクリプトを登録し、JavaScript ファイルと一緒に enqueue_block_editor_assets とロードするためにエンキューします。

変更後、PHP コードは以下のようになります。

<?php

/*
Plugin Name: Sidebar example
*/

function sidebar_plugin_register() {
	wp_register_script(
		'plugin-sidebar-js',
		plugins_url( 'plugin-sidebar.js', __FILE__ ),
		array(
			'react',
			'wp-plugins',
			'wp-edit-post',
			'wp-components'
		)
	);
	wp_register_style(
		'plugin-sidebar-css',
		plugins_url( 'plugin-sidebar.css', __FILE__ )
	);
}
add_action( 'init', 'sidebar_plugin_register' );

function sidebar_plugin_script_enqueue() {
	wp_enqueue_script( 'plugin-sidebar-js' );
	wp_enqueue_style( 'plugin-sidebar-css' );
}
add_action( 'enqueue_block_editor_assets', 'sidebar_plugin_script_enqueue' );

エディターをリロードし、サイドバーを開いてください。

スタイルとコントロールのあるサイドバー

このコードは、データの保存も取得もしません。次のステップでは、メタブロックフィールドとの接続方法を見ていきます。

Top ↑

ステップ 3: メタフィールドの登録

post_meta テーブル内のフィールドを操作するには、register_post_meta を使用して、新しいフィールド sidebar_plugin_meta_block_field を作成します。

注意: このフィールドは REST API から利用可能である必要があります。これは、ブロックエディターが REST API を使用してデータにアクセスするためです。

プラグインの init コールバック関数内に PHP コードを追加してください。

register_post_meta( 'post', 'sidebar_plugin_meta_block_field', array(
	'show_in_rest' => true,
	'single' => true,
	'type' => 'string',
) );

確認するには、ブロックエディタストアにクエリし、フィールドがロードされていることをチェックします。実装後、エディタページをリロードし、ブラウザの開発者コンソールを開いてください。次の JavaScript スニペットを使用して確認します。

wp.data.select( 'core/editor' ).getCurrentPost().meta;

関数は、登録済みのメタフィールドを含むオブジェクトを返します。

コードが undefined を返す場合、投稿の登録時または add_post_type_support 関数で投稿タイプが custom-fields をサポートすることを確認してください。

Top ↑

ステップ 4: 入力コントロールの初期化

エディタストアでフィールドが利用できるようになりました。これで UI を作成できます。入力コントロールを関数に取り出し、将来の機能追加のためにコードをクリーンにします。

( function ( wp ) {
	var el = React.createElement;
	var registerPlugin = wp.plugins.registerPlugin;
	var PluginSidebar = wp.editPost.PluginSidebar;
	var TextControl = wp.components.TextControl;

	var MetaBlockField = function () {
		return el( TextControl, {
			label: 'Meta Block Field',
			value: 'Initial value',
			onChange: function ( content ) {
				console.log( 'content changed to ', content );
			},
		} );
	};

	registerPlugin( 'my-plugin-sidebar', {
		render: function () {
			return el(
				PluginSidebar,
				{
					name: 'my-plugin-sidebar',
					icon: 'admin-post',
					title: 'My plugin sidebar',
				},
				el(
					'div',
					{ className: 'plugin-sidebar-content' },
					el( MetaBlockField )
				)
			);
		},
	} );
} )( window.wp );

MetaBlockField コンポーネント内の値を sidebar_plugin_meta_block_field の値で初期化し、値が変更された際には更新し続けるようにします。

useSelect 関数は、コンポーネントがロードした際にデータを取得し、データが変更されると更新します。以下は、useSelect で更新したコードです。

( function ( wp ) {
	var el = React.createElement;
	var registerPlugin = wp.plugins.registerPlugin;
	var PluginSidebar = wp.editPost.PluginSidebar;
	var Text = wp.components.TextControl;
	var useSelect = wp.data.useSelect;

	var MetaBlockField = function () {
		var metaFieldValue = useSelect( function ( select ) {
			return select( 'core/editor' ).getEditedPostAttribute(
				'meta'
			)[ 'sidebar_plugin_meta_block_field' ];
		}, [] );

		return el( Text, {
			label: 'Meta Block Field',
			value: metaFieldValue,
			onChange: function ( content ) {
				console.log( 'content has changed to ', content );
			},
		} );
	};

	registerPlugin( 'my-plugin-sidebar', {
		render: function () {
			return el(
				PluginSidebar,
				{
					name: 'my-plugin-sidebar',
					icon: 'admin-post',
					title: 'My plugin sidebar',
				},
				el(
					'div',
					{ className: 'plugin-sidebar-content' },
					el( MetaBlockField )
				)
			);
		},
	} );
} )( window.wp );

wp.data.useSelect 関数は、@wordpress/data パッケージにあります。従って、PHP の wp_register_script 関数内の依存に wp-data を追加する必要があります。

注意: getEditedPostAttribute 呼び出しが使用されています。これは、まだ保存されていないユーザーの編集を含む、投稿のもっとも最近の値を取得します。

コードを更新してリロードし、サイドバーを開いて、正常に動作していることを確認してください。入力コントロールのコンテンツはこれまでの Initial value ではなく空白文字列になります。まだ値を入力することはできませんが、エディターストアの値を変更するとコンポーネントが更新されることをチェックできます。ブラウザーのコンソールを開き、次のコードを実行してください。

wp.data
	.dispatch( 'core/editor' )
	.editPost( { meta: { sidebar_plugin_meta_block_field: 'hello world!' } } );

入力コンポーネントのコンテンツが変更されることを確認できます。

Top ↑

ステップ 5: 入力コントロールの変更でメタフィールドを更新する

最後のステップでは入力コンテンツが変更された際にメタフィールドを更新します。useDispatch は、唯一の引数としてストア名を取り、ストアの更新に利用可能なメソッドを返します。この例では、editPost を使用します。

( function ( wp ) {
	var el = React.createElement;
	var registerPlugin = wp.plugins.registerPlugin;
	var PluginSidebar = wp.editPost.PluginSidebar;
	var TextControl = wp.components.TextControl;
	var useSelect = wp.data.useSelect;
	var useDispatch = wp.data.useDispatch;

	var MetaBlockField = function ( props ) {
		var metaFieldValue = useSelect( function ( select ) {
			return select( 'core/editor' ).getEditedPostAttribute(
				'meta'
			)[ 'sidebar_plugin_meta_block_field' ];
		}, [] );

		var editPost = useDispatch( 'core/editor' ).editPost;

		return el( TextControl, {
			label: 'Meta Block Field',
			value: metaFieldValue,
			onChange: function ( content ) {
				editPost( {
					meta: { sidebar_plugin_meta_block_field: content },
				} );
			},
		} );
	};

	registerPlugin( 'my-plugin-sidebar', {
		render: function () {
			return el(
				PluginSidebar,
				{
					name: 'my-plugin-sidebar',
					icon: 'admin-post',
					title: 'My plugin sidebar',
				},
				el(
					'div',
					{ className: 'plugin-sidebar-content' },
					el( MetaBlockField )
				)
			);
		},
	} );
} )( window.wp );

更新後、ユーザーがタイプすると、入力コントロールは editPost を呼び出し、キーを押すたびにエディタストアを更新します。

JavaScript を更新し、サイドバーをロードし、入力フィールドで入力します。ブラウザーの開発コンソールで以下の JavaScript スニペットを実行すると、入力コントロールに入力したものが保存されていることを確認できます。

wp.data.select( 'core/editor' ).getEditedPostAttribute( 'meta' )[
	'sidebar_plugin_meta_block_field'
];

表示されるメッセージは、入力フィールドに入力したものと同じはずです。

記事を保存する際、データベースに正しく保存されることを確認するには、保存後にリロードして、入力コントロールが最後に入力した値で初期化されることを確認してください。

Top ↑

追加リソース

@wordpress/data パッケージ の操作用ドキュメント

このガイドで使用された関数

Top ↑

まとめ

post_meta コンテンツの更新に使用可能な、カスタムサイドバーを作成しました。

完全なサンプルは、block-development-examples リポジトリから、plugin-sidebar サンプルをダウンロードしてください。

Top ↑

注意

エディターの「設定」の「パネル」ページ内で (右上の3つの点から) カスタムフィールドを有効にすると、TextControl と同じ名前のフィールド、この場合は sidebar_plugin_meta_block_field が、エディターウィンドウの下部にあるカスタムフィールドパネルにも表示されます。これら2つのフィールドは、同じメタプロパティにアクセスします。

TextControl とカスタムフィールド

投稿を保存すると、TextControl の値が最初に保存され、次にカスタムフィールドの値が保存されるため、最終的にデータベースに永続化される値はカスタムフィールドの値です。このため、TextControl の値を変更しても、最終的にはカスタムフィールドの値が保存されます。

この問題はカスタムフィールドが有効でなければ発生しません。

カスタムフィールドを有効にし、かつ、サイドバーに投稿メタを表示する必要がある場合は、2つの解決策があります。

  1. メタフィールドの名前の前にアンダースコアを付ける。上の例では名前は _sidebar_plugin_meta_block_field になります。これで投稿メタはプライベートとして扱われるため、投稿のカスタムフィールドセクションに表示されません。ただしこのままでは投稿を保存する際にエラーが発生するため、register_post_meta に渡す args 配列に auth_callback プロパティと、最終的に true を返す関数を追加する必要があります。詳しくは post_meta ページの args ドキュメントを参照してください。
  2. TextControl の onChange 関数内で、Value フィールドの textarea に対して、TextControl の meta フィールド値と同じになるように設定する。両方の場所で値が同じになるため、TextControl で値を変更しても、データベースに保存されることを保証できます。
return el( TextControl, {
  label: 'Meta Block Field',
  value: metaFieldValue,
  onChange: function ( content ) {
    editPost( {
      meta: { sidebar_plugin_meta_block_field: content }
    })
    document.querySelector( {the-value-textarea} ).innerHTML = content;
  },
} );

原文

最終更新日: