メタボックスを使わずにカスタムフィールドの値を追加・更新・削除する方法(リアルタイムコラボレーション対応)

公開日:2026(令和8)年4月24日/最終更新日:

WordPress Customize Ideas | Personal WP Customization Notes (PWCN)

サイトの維持や有用なページの紹介を目的として、このページには各所に広告を表示しています。多数の広告が表示され、閲覧しにくいところがあるかも知れませんが、ご協力いただけますようお願いいたします。

WordPressでカスタムフィールドの操作を編集画面下にあるカスタムフィールド一覧で直接書き換えずに、どこかのパネルで変更させたいという時に使うメタボックス、このページに到達した方は当然これを使ったコードの書き方はご存じでしょう。

でもWordPress 7.0で加わるリアルタイムコラボレーション(共同編集機能)では、メタボックスへの値の変更は基本的にsave_postにフックさせる、つまり「更新」などのボタンをクリックしないと動作しないので、データに不整合が起こる可能性があることから、メタボックスが1つでも存在する編集画面では、設定でリアルタイムコラボレーションを有効にしても機能しないようになっています(他の人が参加しようとすると無理やり編集権限を取り上げるか立ち去るかのいずれかの選択になります)。

これでは使うかどうかは別の話として、せっかくの新機能が使えないようになってしまいます。

そこで考えられるのが、先日公開した「リアルタイムコラボレーション有効化時のメタボックスの扱い方(例)」で書いているように、リアルタイムコラボレーションが有効の場合にはメタボックスを表示しないという方法なのですが、できればそうした制限なく全機能を使えるようにしておきたいものですね。

そこでおすすめなのがメタボックスではなくWordPress標準の「カテゴリー」や「タグ」の設定と同じ仕組みのパネルを用意してREST APIを使って更新する方法。

これを実装する方法を検索したりAIに聞いたりして出てくるのが開発環境用意して、または開発環境ありきのページや回答、私のように開発環境を持たない人にとってはハードルが高いどころかスタートラインにも立てない状況になってあきらめるしかなくなってしまいます。

そこで今回は、脱メタボックス、リアルタイムコラボレーションが問題なく使えるようにする方法を、開発環境なしでも実装できるサンプルコードをいくつか用意して紹介したいと思います。

検索で参考ページをいくつも見ながら、AIに手伝ってもらいながらで結構時間をかけて苦労して完成したものなので私だけの秘密にするつもりでしたが、同じように困っている誰かの一助になれば幸いです..。

本ページでは旧来のカスタムフィールド値設定窓をメタボックス(これはWordPress公式の呼称)、今回紹介するREST API経由でのカスタムフィールド値設定窓をメタパネル(これは私が勝手に命名)と呼ぶことにしますので以後読み替えてください

コードサンプル含めかなりの長文になりますので、ブックマークなどしてじっくりとお読みください

なお、長年WordPressでのカスタマイズを行っているものの、私自身JS、今回のようなメタパネル追加や独自ブロックを追加するなどといった、特にブロックエディターに何かの変更を加えるものについては初心者に近いです。本ページはそんな私でもAIの力を借りてメタパネルの実装ができ、こうして解説記事として公開することで自身の理解の深耕も兼ねていることを予めお断りしておきます。

コードを使用する前に、ここをクリックして注意事項をご確認ください

本ページで掲載しているコードは、以下に了承した上で使用ください

  • コードは商用・非商用問わず自由に使っていただいて構いませんが、コード追加による不具合やトラブルが発生しても当方では一切責任を負いません
  • コードは有効化しているテーマのfunctions.php、style.cssなどへ追加することで機能します。それらのファイルへの変更を行うことに不安のある方は使用しないでください
  • コードは本ページの公開日時点で私の環境において動作したものです。WordPressバージョン他環境の違いによって動作しないことがあります
  • コードは、セキュリティ、コードの正確さなどにおいて完全なものではありません。中には紹介するコードを簡略化するために省略している部分があるものもありますので、ご自身でコードを十分に検証し、必要な部分の編集を行った上で使用するようにしてください
  • 掲載しているのは参考コードです。自身の環境に合わせるための編集はご自身で対応いただく必要があります(コメント欄等から質問いただいても基本回答は致しません)
  • 掲載しているコードの転載を禁じます(SNSで紹介いただいたり、本ページへのリンクを張っていただくことは大歓迎です)

標準のカスタムフィールド一覧を無効にする【必須の前準備】

本ページのサンプルコードを使ってメタパネルが追加され、入力された値がきちんと更新されているかを、標準のカスタムフィールド一覧で確認するというのは、メタボックス時代ではよくあるケースですね。

でも、今回のカスタムパネルを使用する方法の場合はREST APIを使用するため、カスタムフィールド一覧が編集画面内に存在している状態だと、「REST API使って値を書き換えようとしたけど、旧来のカスタムフィールドの入力欄(一覧)があるからそちらが優先だな」と判断して、メタパネル内に入力した値が更新されないという現象が発生します。

これは、例えば本ページで紹介するサンプルコードのまま(つまり今まで一度も使われていないカスタムフィールド名)の場合には、存在しないので最初に設定・入力した値は保存されますが、値を変えて更新する際には最初の設定値に戻ってしまうという、一見不具合やクソコードなのでは?と感じる挙動になります。

実はこの現象が発生するのがまさか「カスタムフィールド一覧」を表示しているからだと思わず結構な時間いろいろなデバッグを行った結果、実装不能と一時判断した時間もありましたので、私と同じ現象に徒労しないよう、以下のコードを使って「カスタムフィールド一覧」を無効にし、ブロックエディターの「設定」メニューでも「カスタムフィールド」の有効/無効スイッチが出ないようにする措置をしておきましょう。

※簡易な処理なので無名関数のままにしていますが、ユーザー定義関数化したい方はご自身で変換してください

add_action( 'init', function() {
	remove_post_type_support( 'post', 'custom-fields' );
} );

メタパネルを実装するサンプルコード

必ず前項の「標準のカスタムフィールド一覧を無効にする」を確実に行ってから先に進んでください

前準備

どんなサイトでも構いませんし、有効化しているテーマはブロックテーマ・クラシックテーマに関わらずブロックエディターが正常に動作すれば何でも構いませんが、きちんと動作するのかを確認しやすくするため、できればテスト用サイトを用意して、Twenty Twenty-FiveなどWordPressのデフォルトテーマとして採用されていて、かつ、functions.phpが標準で存在するテーマを使ってテストすることをおすすめします。

また、最終的にリアルタイムコラボレーションが利用できることの確認、メタパネルでの値変更が共同編集者すべての編集画面で即座に反映されるかも確認いただきたいので、既存のサイトでテストされる場合は、メタボックスを表示する機能をコードで追加している場合は停止し、投稿編集画面に何等かのメタボックスを出力するプラグインは停止していただくと、スムーズに実装まで進められると思います。

ブロックエディターによる投稿の編集ができているサイトであれば問題ないかとは思いますが、メタパネルはREST APIを使ってデータの更新を行うものですので、REST APIに対して何かの制限を行うコードやプラグインがある場合は一応そちらも停止してください

メタパネルを追加して機能するようにするには、functions.phpに書くPHPコードと、実際にパネルを表示させて動作をさせるJavaScriptが必要となります。

「pwcn-metapanel.js」というファイルをテーマフォルダ直下に追加して以下のコードをfunctions.phpへ追加しておいてください。

function pwcn_meta_panel_js_init(){
	wp_enqueue_script(
		'pwcn-meta-panel-js',
		get_template_directory_uri() . '/pwcn-metapanel.js', 
		[ 'wp-plugins', 'wp-edit-post', 'wp-element', 'wp-components', 'wp-data', 'wp-i18n' ],
		filemtime( get_template_directory() . '/pwcn-metapanel.js' )
	);
}
add_action('enqueue_block_editor_assets','pwcn_meta_panel_js_init');

文字列を保存させるためのメタパネルのサンプルコード

まずはメタパネルを作ってテキスト入力窓を表示させ、そこに入力した文字列がカスタムフィールド値として保存されるようにするサンプルコードを紹介します。その後それを基本として詳しく説明をさせていただき、「テキストエリア(長文用)」「チェックボックス」「ラジオボタン」「セレクトボックス」「カスタムフィールドの操作を行わない説明欄」のサンプルコードを紹介しますので、どこがどう違うのかを見比べて実装に役立ててください。

functions.phpへのコード追加

/*** テキストのサンプル ***/
add_action( 'init', function() {
	register_post_meta( 'post', 'my_custom_text', [
		'show_in_rest' => true,      // これでREST APIの "meta" 内に出現する
		'single'       => true,
		'type'         => 'string',
		'auth_callback' => function() {
			return current_user_can( 'edit_posts' );
		},
	] );
} );

※無名関数にしていますので、ユーザー定義関数を使いたい方はご自身で書き換えてください

pwcn-metapanel.jsへのコード追加

以下のコードを「pwcn-metapanel.js」へ追加してください。

//テキストボックスの場合のJS
(function (wp) {
	/*** 必要な関数やツールの準備 ***/
	// Reactの要素を作成するための関数(PHPのHTML出力に相当する役割)
		var el = wp.element.createElement;
	// 作成したパネルをWordPressのエディターに正式に登録するための関数
		var registerPlugin = wp.plugins.registerPlugin;
	// 投稿設定サイドバー(右側の「投稿」タブ)の中に新しいパネル(アコーディオン)を作るための部品
		var PluginDocumentSettingPanel = wp.editor.PluginDocumentSettingPanel || wp.editPost.PluginDocumentSettingPanel;
	// データベース(メタデータ)から現在の値を取得するための「読み込み」用ツール
	var useSelect = wp.data.useSelect;
	// 入力された値をデータベースへ反映( dispatch )するための「書き込み」用ツール
	var useDispatch = wp.data.useDispatch;
	// 1行のテキスト入力欄を表示する
	var TextControl = wp.components.TextControl;

	/*** メタパネルの定義 ***/
	var MyCustomPanel = function () { //MyCustomPanelという名前の領域にパネルを追加する
		// 1. 現在のメタデータを取得
		var meta = useSelect(function (select) {
			return select('core/editor').getEditedPostAttribute('meta') || {};
		}, []);

		// 2. 更新用関数を取得
		var { editPost } = useDispatch('core/editor');

		return el(
			PluginDocumentSettingPanel,
			{
				//パネルの名前、文字列、アイコンを指定
				//nameはサイト内で一意である必要がある点に注意
				name: 'my-custom-panel',
				title: 'テキストパネル',
				icon: 'admin-generic',
			},
			//TextControl(文字列)として処理
			el(TextControl, {
				//入力欄の上に表示する説明
				label: '文字列', 
				//register_post_metaの第一引数でmy_custom_textという名前をつけたフィールドの値を表示
				value: meta['my_custom_text'] || '',
				__next40pxDefaultSize: true,
				onChange: function (newValue) {
					// 3. メタデータの特定キーだけを上書きして送信
					editPost({
						meta: {
							//register_post_metaの第一引数でmy_custom_textという名前をつけたフィールドを更新
							my_custom_text: newValue
						}
					});
				}
			})
		);
	};

	//MyCustomPanelという領域にmy-custom-panel-pluginという名前のパネルを出力する
	//領域やパネル名は一意である必要がある点に注意
	registerPlugin('my-custom-panel-plugin', { render: MyCustomPanel });

})(window.wp);

動作テスト

コードを紐解く前に、とにかく動作するかを見てみたいと思いますので、早速確認してみましょう。

投稿編集画面(既存の投稿でも、新規投稿でもOK)を開き、右サイドパネルにある「投稿」タブ(アイキャッチ画像などがあるパネルの集まり)を表示させて、下へスクロールしていくと、下図左のように「テキストパネル」というのが表示されているはずです。

そして「テキストパネル」をクリックすると、下図右のように「文字列」というタイトルの入力窓が表示されているはずです。

メタボックスを使わずにカスタムフィールドの値を追加・更新・削除する方法(リアルタイムコラボレーション対応)|Personal WP Customization Notes (PWCN)
メタボックスを使わずにカスタムフィールドの値を追加・更新・削除する方法(リアルタイムコラボレーション対応)|Personal WP Customization Notes (PWCN)

さらに入力窓に何か文字列を入力してみてください。入力した段階でカスタムフィールドの値をこの値にする準備が整い、「下書き保存」「公開」「更新」などをクリックすることで確定されるという流れで値が確実に書き換わるはずです。

入力値を変更した段階では準備ができているだけで実際の書き換えはされないため、保存ボタンをクリックしないで編集画面をリロードしたり編集画面から移動しようとすると以下のような警告が表示され、そのまま閉じると変更値は保存されない点に注意してください

ここまで来たらひとまずメタボックスを使わずにカスタムフィールドの値を更新する機構が完成しました。ついでにメタパネルにする最大の目的であるリアルタイムコラボレーションの動作確認をしておきましょう。

リアルタイムコラボレーションの確認

リアルタイムコラボレーション(共同編集)機能はWordPress7.0から利用できる機能ですので、7.x正式リリース前であればWordPress Beta Testerを使って7.0RCなどのバージョンにしてください。

WordPress 7.x以降になっていれば、管理画面の「設定」→「投稿設定」を開くと「共同編集」というチェック欄があるので有効化して設定を保存します。

次に共同編集のテストを行うユーザーが必要ですので、ユーザーの新規作成(投稿者権限以上)を行ってください。

下書き済でも公開済みでもいいので、投稿の編集画面を開きます(新規作成の場合は何かのブロックを追加して下書き保存してください)。※この画面は開いたままにしてください。

別のブラウザ、またはシークレットウインドウを開いて同じサイトのログイン画面を開き、先ほど作成したユーザーでログインし、投稿一覧画面を開き、(編集中)となっている投稿の「参加」をクリックして編集画面を開いてください。

投稿編集画面に何の警告画面も表示されなければこの段階で共同編集ができる状態になっています。もしも「引き継ぐ」「キャンセル」などというボタンと警告文が表示される場合は、手順に誤りがあるか、メタボックスが含まれる投稿を開いていることが原因なので諸所確認ください。

双方の編集画面で、ブロックを追加・編集したりして、リアルタイムに編集画面の内容が変わるかを確認します(結構感動します)。その後、メタパネルに入力した文字を変更してみて、別ユーザーの編集画面でもその値がリアルタイムに書き換わるかを確認してください(こちらも結構感動します)。

ちなみにページ冒頭などでちらっと触れましたがメタボックスが1つでも存在している投稿の編集画面ではリアルタイムコラボレーション(共同編集)は無効になります(そもそもこの問題を解決したくて本ページをご覧になっているはずです)。

コードの簡易解説とまとめ

以下がメタパネルを動作させるための大まかな流れです。

以下がJSコードの大まかな流れです。私のようにJSに明るくない人でなくても分かるよう、前述のJSコードにはたくさんコメントを入れていますので見比べながら確認してみてください。

  • WordPress本体からいろいろな定義や動作を行うプログラムを起動させるための記述
  • どの領域にメタパネルを追加するのかで囲む
  • 領域内のメタパネル内で操作するカスタムフィールドのキーとパネル内の文字列、値の引き出しと更新
  • メタパネルの内容でブロックエディターへパネルを展開する

つまりPHP側ではカスタムフィールドキーの登録をして、REST APIを使って値の引き出しと更新をしますよ!としているだけで、あとはJS側が処理するということなんですね。

前述のコードで動作が確認できたら、タイトルやフォーム上の文字を変更したり、領域名を変更したりしてどのように変化するのか、どことどこを共通にしたりどこにキーを入れたりすればいいのかなどを試した後、例えば同じ流れのものを追加して編集して複数の文字列メタパネルを操作できるようにしてみるなど、コード体系と編集点を確認しつつ遊んでみてください。

複数のメタパネルの一括設定は慣れてからの方がいいかも

ここまで紹介したようにPHPとJSの呼応によって1つのメタパネルが完成することから、1つのJSファイル内に複数のパネルや領域のJSコードを挿入しても呼応するPHPコードがあればきちんと動作します。

更に、JSコード冒頭の定義部分が共通で領域が共通なものは、メタパネルの表示と動作部分を1つのJSコードのまとまりの中に書いたりすることもできます。

また、複数のコントロール用の定義をまとめておき、領域内に複数のコントロールを持つメタパネルを追加していくこともできます。

が、コードの流れと体系が分からないままこれらのことをしていくと、後々コードを見て「ここ何だっけ?やってみたけど動かない」という事態を招きかねません。

JSの定義部分については重複して記述があっても1回だけ読み込まれる(重複していれば読み込み済としてスキップされる)だけですし、同一領域へメタパネルを追加する記述の塊があってもきちんとその領域内に展開されますし、これらが重複していても人間には分からない位の一瞬の判断で処理が行われますから、「もうメタパネルについては空でもコードが書ける」位になるまでは、まとめて書かないようにしておいた方が無難だと思います。

ここまでで、メタパネルの基本的なコード体系、どのように動作するのか、リアルタイムコラボレーションが使えるようになることは確認いただけたと思います。

実際の運用ケースでは、テキスト入力以外の入力コントロールを行うことがほとんどだと思いますので、ここからは前述の文字列メタパネルのコードを一部変更していろいろなコントロール(入力・指定の方法)ができるようにするコード例を紹介していきます。

文字列メタパネルとのコードの違いなどを見ながら実装してみてくださいね。

テキストエリア(長文用)

文字列メタパネルの際と同様にPHPはfunctions.phpへ、JSはpwcn-metapanel.jsへコードを追加し、投稿編集画面を開きなおして動作確認をしてください(パネルが表示されない場合はキャッシュのクリアやコードの再確認をしてみてください)。

PHPコード

/*** テキストエリアのサンプル ***/
add_action( 'init', function() {
	register_post_meta( 'post', 'my_custom_text_area', [
		'show_in_rest' => true,      // これでREST APIの "meta" 内に出現する
		'single'       => true,
		'type'         => 'string',
		'auth_callback' => function() {
			return current_user_can( 'edit_posts' );
		},
	] );
} );

※無名関数にしていますので、ユーザー定義関数を使いたい方はご自身で書き換えてください

JSコード

//テキストエリアの場合のJS(入力文字列カウント付き)
(function (wp) {
	var el = wp.element.createElement;
	var registerPlugin = wp.plugins.registerPlugin;
	var PluginDocumentSettingPanel = wp.editor.PluginDocumentSettingPanel || wp.editPost.PluginDocumentSettingPanel;
	var useSelect = wp.data.useSelect;
	var useDispatch = wp.data.useDispatch;
	var TextareaControl = wp.components.TextareaControl; //テキストエリアの場合

	var MyCustomPanel = function () {
		// 1. 現在のメタデータを取得
		var meta = useSelect(function (select) {
			return select('core/editor').getEditedPostAttribute('meta') || {};
		}, []);

		var { editPost } = useDispatch('core/editor');

		// 現在の値を定数に入れておく(文字数計算用)
		var currentValue = meta['my_custom_text_area'] || '';
		var charCount = currentValue.length;

		return el(
			PluginDocumentSettingPanel,
			{
				name: 'my-custom-textarea-counter',
				title: 'テキストエリアパネル',
				icon: 'edit',
			},
			el('div', {},
				// メインのテキストエリア
				el(TextareaControl, {
					label: '長文文字列',
					value: currentValue,
					rows: 5, //行数
					onChange: function (newValue) {
						editPost({
							meta: { my_custom_text_area: newValue }
						});
					}
				}),
				// 文字数カウンターの表示
				el('div', { 
					style: { 
						textAlign: 'right', 
						fontSize: '12px', 
						color: charCount > 120 ? '#d94f4f' : '#666', // 120文字を超えたら赤くする例
						marginTop: '0', // TextareaControlとの隙間を調整
						paddingBottom: '10px'
					} 
				},
				charCount + ' 文字'
				)
			)
		);
	};

	registerPlugin('my-custom-textarea-counter-plugin', { render: MyCustomPanel });

})(window.wp);

チェックボックス

文字列メタパネルの際と同様にPHPはfunctions.phpへ、JSはpwcn-metapanel.jsへコードを追加し、投稿編集画面を開きなおして動作確認をしてください(パネルが表示されない場合はキャッシュのクリアやコードの再確認をしてみてください)。

PHPコード

/*** チェックボックスのサンプル ***/
add_action( 'init', function() {
	register_post_meta( 'post', 'my_custom_check', [
		'show_in_rest' => true,
		'single'       => true,
		'type'         => 'boolean', // 真偽値として定義
		'auth_callback' => function() {
			return current_user_can( 'edit_posts' );
		},
	] );
} );

※無名関数にしていますので、ユーザー定義関数を使いたい方はご自身で書き換えてください

JSコード

//チェックボックスのJS
(function (wp) {
	var el = wp.element.createElement;
	var registerPlugin = wp.plugins.registerPlugin;
	var PluginDocumentSettingPanel = wp.editor.PluginDocumentSettingPanel || wp.editPost.PluginDocumentSettingPanel;
	var CheckboxControl = wp.components.CheckboxControl;
	var useSelect = wp.data.useSelect;
	var useDispatch = wp.data.useDispatch;

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

		var { editPost } = useDispatch('core/editor');

		return el(
			PluginDocumentSettingPanel,
			{
				name: 'my-custom-check-panel',
				title: '機能設定',
				icon: 'admin-settings',
			},
			el(CheckboxControl, {
				label: 'この機能を有効にする',
				help: 'チェックを入れるとフロントエンドで特定の機能が動作します。',
				checked: !!meta['my_custom_check'], // 二重否定(!!)で確実に boolean 型に変換
				onChange: function (newValue) {
					editPost({
						meta: {
							my_custom_check: newValue // newValue には true/false が入る
						}
					});
				}
			})
		);
	};

	registerPlugin('my-custom-check-plugin', { render: MyCustomPanel });

})(window.wp);

ラジオボタン

文字列メタパネルの際と同様にPHPはfunctions.phpへ、JSはpwcn-metapanel.jsへコードを追加し、投稿編集画面を開きなおして動作確認をしてください(パネルが表示されない場合はキャッシュのクリアやコードの再確認をしてみてください)。

PHPコード

/*** ラジオボタンのサンプル ***/
add_action( 'init', function() {
	register_post_meta( 'post', 'my_custom_button', [
		'show_in_rest' => true,
		'single'       => true,
		'type'         => 'string', // ラジオボタンの値('option1'など)を保存するためstring
		'auth_callback' => function() {
			return current_user_can( 'edit_posts' );
		},
	] );
} );

※無名関数にしていますので、ユーザー定義関数を使いたい方はご自身で書き換えてください

JSコード

//ラジオボタンの場合のJS
(function (wp) {
	var el = wp.element.createElement;
	var registerPlugin = wp.plugins.registerPlugin;
	var PluginDocumentSettingPanel = wp.editor.PluginDocumentSettingPanel || wp.editPost.PluginDocumentSettingPanel;
	var useSelect = wp.data.useSelect;
 	var useDispatch = wp.data.useDispatch;
	var RadioControl = wp.components.RadioControl; // ラジオボタン用

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

		var { editPost } = useDispatch('core/editor');

		return el(
			PluginDocumentSettingPanel,
			{
				name: 'my-custom-radio-panel',
				title: 'ボタン設定パネル',
				icon: 'admin-settings',
			},
			el(RadioControl, {
				label: '表示モードを選択',
				selected: meta['my_custom_button'] || 'default', // 現在の値(未設定ならdefault)
				options: [
					{ label: '標準(Default)', value: 'default' },
					{ label: '目立たせる(Highlight)', value: 'highlight' },
					{ label: '隠す(Hidden)', value: 'hidden' },
				],
				onChange: function (newValue) {
					editPost({
						meta: {
							my_custom_button: newValue
						}
					});
				}
			})
		);
	};

	registerPlugin('my-custom-radio-plugin', { render: MyCustomPanel });

})(window.wp);

セレクトボックス

文字列メタパネルの際と同様にPHPはfunctions.phpへ、JSはpwcn-metapanel.jsへコードを追加し、投稿編集画面を開きなおして動作確認をしてください(パネルが表示されない場合はキャッシュのクリアやコードの再確認をしてみてください)。

PHPコード

/*** セレクトボックスのサンプル ***/
add_action( 'init', function() {
	register_post_meta( 'post', 'my_custom_selection', [
		'show_in_rest' => true,
		'single'       => true,
		'type'         => 'string',
		'auth_callback' => function() {
			return current_user_can( 'edit_posts' );
		},
	] );
} );

※無名関数にしていますので、ユーザー定義関数を使いたい方はご自身で書き換えてください

JSコード

//セレクトボックスのJS
(function (wp) {
	var el = wp.element.createElement;
	var registerPlugin = wp.plugins.registerPlugin;
	var PluginDocumentSettingPanel = wp.editor.PluginDocumentSettingPanel || wp.editPost.PluginDocumentSettingPanel;
	var SelectControl = wp.components.SelectControl; // ここを変更
	var useSelect = wp.data.useSelect;
	var useDispatch = wp.data.useDispatch;

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

		var { editPost } = useDispatch('core/editor');

		return el(
			PluginDocumentSettingPanel,
			{
				name: 'my-custom-select-panel',
				title: '表示設定',
				icon: 'admin-settings',
			},
			el(SelectControl, {
				label: '表示モードを選択',
				// RadioControlでは "selected" でしたが、SelectControlでは "value" を使います
				value: meta['my_custom_selection'] || 'default', 
				options: [
					{ label: '選択1(Default)', value: 'default' },
					{ label: '選択2', value: 'highlight' },
					{ label: '選択3', value: 'hidden' },
				],
				onChange: function (newValue) {
					editPost({
						meta: {
							my_custom_selection: newValue
						}
					});
				}
			})
		);
	};

	registerPlugin('my-custom-select-plugin', { render: MyCustomPanel });

})(window.wp);

カスタムフィールドの操作を行わない説明欄

文字列メタパネルなどのように入力窓が必要ないため、PHPへのコード追加はありません。JSはpwcn-metapanel.jsへコードを追加し、投稿編集画面を開きなおして動作確認をしてください(パネルが表示されない場合はキャッシュのクリアやコードの再確認をしてみてください)。

JSコード

//メッセージのみを表示したい場合のJS
(function (wp) {
	var el = wp.element.createElement;
	var Notice = wp.components.Notice; //WP標準の警告や通知などの背景スタイルを使いたい場合
	var ExternalLink = wp.components.ExternalLink; //外部ページへのリンクを使いたい場合は追加
	var registerPlugin = wp.plugins.registerPlugin;
	var PluginDocumentSettingPanel = wp.editor.PluginDocumentSettingPanel || wp.editPost.PluginDocumentSettingPanel;

	var MyNoticePanel = function () {
		return el(
			PluginDocumentSettingPanel,
			{
				name: 'my-notice-panel',
				title: '【重要】設定上の注意',
				icon: 'info-outline', // インフォメーションアイコン
			},
			// パネルの内部コンテンツ
			el('div', { style: { padding: '10px 0' } },
				el('p', { style: { fontSize: '13px', lineHeight: '1.5', color: '#1e1e1e' } },
					'説明文のみを出力するパネルです',
				el('br'),
                    '文字列やリンクなどいろいろなことを表示させることができます'
				),
				el('p', { style: { marginTop: '10px', fontWeight: '600' } },
					'⚠️ 注意:',
					el('br'),
					'JSの作法に従ってHTMLタグを使って記述していきます'
				),
				el(ExternalLink, { href: 'https://example.com/docs' }, '詳細なマニュアルはこちら'),
				el(Notice, { 
					status: 'warning', // 'error', 'info', 'success', 'warning'
					isDismissible: false // 消去ボタンを隠す
				}, '内部にこのような警告文を表示することもできます')
			)
		);
	};

	registerPlugin('my-notice-panel-plugin', { render: MyNoticePanel });

})(window.wp);

メタボックス方式からの移行方法、既知の懸念点など

メタボックスからメタパネルへの移行方法の例

カスタムフィールドの追加ではなく登録を行う

通常「add_post_meta()」を使っていろいろな設定値を指定した後に「add_metaboxes」や「admin_init」へフックさせてメタボックスを表示させるのがコードの流れですが、メタパネルでは登録したカスタムフィールドの設定を元にJSで情報を読み書きする窓を作るという流れになります。従って、前項のサンプル(以下に再掲)のように、PHPでは「register_post_meta()」を使い、REST APIから利用できるようにする条件を追加します。

/*** テキストのサンプル ***/
add_action( 'init', function() {
	register_post_meta( 'post', 'my_custom_text', [
		'show_in_rest' => true,      // これでREST APIの "meta" 内に出現する
		'single'       => true,
		'type'         => 'string',
		'auth_callback' => function() {
			return current_user_can( 'edit_posts' );
		},
	] );
} );

ユーザー定義関数を使う場合は以下のような形になります。

/*** テキストのサンプル ***/
function pwcn_register_my_custon_text_field(){
	register_post_meta( 'post', 'my_custom_text', [
		'show_in_rest' => true,      // これでREST APIの "meta" 内に出現する
		'single'       => true,
		'type'         => 'string',
		'auth_callback' => function() {
			return current_user_can( 'edit_posts' );
		},
	] );
add_action('init','pwcn_register_my_custon_text_field');

上記のコードをこれまでのadd_post_meta()が書かれている関数の下あたりにコピーし、書かれているカスタムフィールドキーをこれまでのキーと同一にします(独自のユーザー定義関数の形にする場合はサイト上で重複しない関数名に書き換えてください)。

一旦add_post_meta()を適用させる以下のようなアクションフックをコメントアウトして無効にします。

//add_action('add_meta_boxes','pwcn_register_my_custon_text_field');
//add_action('admin_init','pwcn_register_my_custon_text_field');

完了したら、本ページのJSを参考にこのカスタムフィールドキーに対応するJSを作り、読み込ませます。

投稿編集画面を開き、メタパネルが表示され、今まで入力したメタキーに対する値が表示されていること、更新が問題なくできることが確認できれば移行自体は完了です。

今まで使用していたメタボックスが不要な場合はこのままコメントアウトしておいてもいいですし、add_post_meta()のあるユーザー定義関数、参照しているコールバック関数、アクションフックを削除すればメタボックスからメタパネルへの完全移行は完了です。

アクションフックをコメントアウトしないまま移行を行うと思わぬトラブルになる可能性がありますし、何度も申し上げている通りメタボックスがあるとリアルタイムコラボレーションは使えませんのでご注意ください

クラシックエディターではメタパネルは使えません。もしもクラシックテーマでもカスタムフィールドのフォームによる編集をしたい方はこちらのページを参考にしながら両立させるのも手かも知れませんが、ブロックエディターを常用している、またはブロックエディターのみに対応させるのであればこれら旧メタボックス用コードは不要になります。

メタボックスとの違い

メタボックスは追加すると、コードの書き方によって「右サイドバー(カテゴリー設定などの下)」か「編集画面の下部(カスタムフィールド一覧の上など)」に配置され、WordPress標準のメタパネルの下であれば、上下の移動やサイドから本文下、本文下からサイドへの移動もできるようになっています。

しかしながら、メタパネルは、基本的にはサイドバーの中以外の場所には配置できず、コードの読み込み順によって表示位置が決まり、移動することもできません。テストした感触では基本的に「プラグイン」「テーマ」「WordPress標準」の順でコードの読み込み順に配置されるようですから、位置を変えれるようにしたい、長文などを本文下で入力させたいなどといったケースではメタボックスを利用したほうがいいかも知れません。

【考察】メタボックスの今後

今回のように、WordPressは今までPHPで何かを行っていたものから、ブロックエディターの導入によって、REST APIを使って更新していく形のものが増えていくことが予想されます。

ただWordPressは必ず新機能が出ると旧来の方式に対する互換性の維持ができるように、いろいろな方が試行錯誤して方法を見つけ出してくれるありがたいCMSでもあります(私の経験上この機能は完全廃止というのはなかったように思います)。

今回のリアルタイムコラボレーション(RTCと公式では略されています)でのメタボックスの扱いに関しては、RTCの導入以前からメタボックスが保存時に情報を更新する=リアルタイムに更新がかからない=データの不整合が起こるという懸念に関していろいろと議論が行われ、RTCは導入することとし、メタボックスがある場合にはRTCを有効にしていたとしても機能させないように一旦するという形になったようです。

今後この問題については継続して議論されていき、例えばメタボックスのままリアルタイムに更新するようなフック等が作られたりして対応できるようになるなどといった対応がなされるか、今回のようにPHPとJS(基本開発環境でそれなりの知識を持って記述しないと実装困難な形)ではなく、同じく7.0で追加されたPHPのみでブロックを作れるようにするといったような形でPHPだけでメタパネルが作れるようになったりという対応がされるかも知れません。

最もメタボックスで弊害が出るのは現状RTCだけなので、RTCを使わないことが前提であれば(自身で更新するだけ、または共同編集する必要がないのであれば)、現状のメタボックスの形でも構いませんし、以下のページのように一旦RTC有効化時にはメタボックスを表示させないようにするといった措置でいいかも知れません。

さらに言えば、サイトにインストールしているメタボックスを使うプラグイン(特にSEOやセキュリティ系のプラグイン)すべてが今回のようにメタパネルにしたり、RTC有効化時にはメタボックスの表示を無効にしたりといった措置を講じなければRTCは使えない話ですから、未来のためにどうしておくべきかを考えて、メタパネルを使用するかの判断をするといいと思います。

, , , , , , , ,
Lolipop ServerMoshimo Ad x-serverMoshimo Ad

WordPress Customize Ideas | Personal WP Customization Notes (PWCN)
リアルタイムコラボレーション有効化時のメタボックスの扱い方(例)