2026年10月13日

2026年10月13日

ブロックエディターにサイドバーパネルを追加する方法|PluginDocumentSettingPanelとPluginSidebar

ブロックエディター(Gutenberg)では、投稿ごとの設定を、右側の設定サイドバーに自分のパネルとして追加できます。昔のクラシックエディターでメタボックスを作っていた用途は、多くがこの方法に置き換えられます。

この記事では、次の2つを1つのプラグインとして作ります。

  • PluginDocumentSettingPanel: 「投稿」タブの中に、注目記事・読了時間・編集メモを入力するパネルを追加する(値は投稿のメタデータに保存)
  • PluginSidebar: 上部のツールバーから開く独立したサイドバーに、題名と本文の文字数を表示する

2026年10月時点のWordPressと @wordpress/scripts を前提にしています。PluginSidebar などは WordPress 6.6 で @wordpress/edit-post から @wordpress/editor に移ったため、プラグインの動作条件を 6.6 以上にしています。コードは @wordpress/scripts 37.1.0 でビルドできることを確かめています。

できあがりのファイル構成

wpdr-editor-panel/
├── wpdr-editor-panel.php   プラグイン本体(メタの登録とスクリプトの読み込み)
├── package.json
├── src/
│   ├── index.js            設定パネル(エントリーポイント)
│   └── sidebar.js          統計サイドバー
└── build/                  npm run build で作られる
    ├── index.js
    └── index.asset.php

手順1: ビルド環境を用意する

Node.js(LTS版)と npm を入れたパソコンで、wp-content/plugins の下にフォルダーを作ります。

cd wp-content/plugins
mkdir wpdr-editor-panel
cd wpdr-editor-panel
npm init -y
npm install --save-dev @wordpress/scripts

package.json の scripts を次のように書き換えます。

{
  "scripts": {
    "start": "wp-scripts start",
    "build": "wp-scripts build"
  }
}

wp-scripts は、既定で src/index.js を読み込んで build/index.js を作ります。同時に、スクリプトが使う WordPress のパッケージ(wp-plugins、wp-editor など)を並べた build/index.asset.php も作ります。@wordpress/editor などのパッケージは WordPress 本体のものを使うので、npm で個別に入れる必要はありません。

手順2: メタデータを登録してスクリプトを読み込む

wpdr-editor-panel.php を作ります。

<?php
/**
 * Plugin Name: WPDR Editor Panel
 * Description: ブロックエディターに記事の設定パネルと統計サイドバーを追加する
 * Version: 1.0.0
 * Requires at least: 6.6
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

// メタデータを登録し、REST API(ブロックエディター)から読み書きできるようにする
add_action( 'init', function () {
	$metas = array(
		'_wpdr_is_featured'  => array( 'type' => 'boolean', 'default' => false ),
		'_wpdr_reading_time' => array( 'type' => 'integer', 'default' => 0 ),
		'_wpdr_note'         => array( 'type' => 'string', 'default' => '' ),
	);
	foreach ( $metas as $key => $args ) {
		register_post_meta(
			'post',
			$key,
			array(
				'type'          => $args['type'],
				'default'       => $args['default'],
				'single'        => true,
				'show_in_rest'  => true,
				'auth_callback' => function ( $allowed, $meta_key, $post_id ) {
					return current_user_can( 'edit_post', $post_id );
				},
			)
		);
	}
} );

// ブロックエディターでだけスクリプトを読み込む
add_action( 'enqueue_block_editor_assets', function () {
	$asset_file = plugin_dir_path( __FILE__ ) . 'build/index.asset.php';
	if ( ! file_exists( $asset_file ) ) {
		return;
	}
	$asset = include $asset_file;
	wp_enqueue_script(
		'wpdr-editor-panel',
		plugins_url( 'build/index.js', __FILE__ ),
		$asset['dependencies'],
		$asset['version'],
		true
	);
} );

ポイントは次のとおりです。

  • ブロックエディターは REST API を通して投稿を読み書きするので、show_in_rest を true にしないと、JavaScript からメタを読めず、保存もされません
  • メタキーを _ で始めると「保護されたメタ」になり、カスタムフィールドの欄に表示されません。この場合、auth_callback で編集を許可しないと REST API から書き込めません。ここでは、その投稿を編集できるユーザーに許可しています
  • 投稿タイプが custom-fields をサポートしていないと、REST API にメタが出ません。標準の「投稿」はサポートしています。カスタム投稿タイプに使う場合は register_post_type() の supports に custom-fields を入れます
  • type は、保存時の値の検証に使われます。integer のメタに数字でない値を送ると、保存でエラーになります

enqueue_block_editor_assets はブロックエディターを開いたときにだけ実行されるので、サイトの表側には読み込まれません。

手順3: 設定パネルを作る(PluginDocumentSettingPanel)

src/index.js を作ります。

import { registerPlugin } from '@wordpress/plugins';
import { PluginDocumentSettingPanel } from '@wordpress/editor';
import { useSelect, useDispatch } from '@wordpress/data';
import { store as editorStore } from '@wordpress/editor';
import {
	TextareaControl,
	ToggleControl,
	TextControl,
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import './sidebar';

function ArticleSettingsPanel() {
	const { editPost } = useDispatch( editorStore );

	const { postType, meta } = useSelect( ( select ) => {
		const { getCurrentPostType, getEditedPostAttribute } =
			select( editorStore );
		return {
			postType: getCurrentPostType(),
			meta: getEditedPostAttribute( 'meta' ) || {},
		};
	}, [] );

	// 投稿(post)の編集画面だけに表示する
	if ( postType !== 'post' ) {
		return null;
	}

	const updateMeta = ( key, value ) => {
		editPost( { meta: { [ key ]: value } } );
	};

	return (
		<PluginDocumentSettingPanel
			name="wpdr-article-settings"
			title={ __( '記事の詳細設定', 'wpdr-editor-panel' ) }
		>
			<ToggleControl
				__nextHasNoMarginBottom
				label={ __( '注目記事にする', 'wpdr-editor-panel' ) }
				checked={ !! meta._wpdr_is_featured }
				onChange={ ( value ) =>
					updateMeta( '_wpdr_is_featured', value )
				}
			/>
			<TextControl
				__next40pxDefaultSize
				__nextHasNoMarginBottom
				label={ __( '読了時間(分)', 'wpdr-editor-panel' ) }
				type="number"
				min={ 0 }
				value={ meta._wpdr_reading_time ?? 0 }
				onChange={ ( value ) =>
					updateMeta(
						'_wpdr_reading_time',
						parseInt( value, 10 ) || 0
					)
				}
			/>
			<TextareaControl
				__nextHasNoMarginBottom
				label={ __( '編集メモ(公開されません)', 'wpdr-editor-panel' ) }
				value={ meta._wpdr_note ?? '' }
				onChange={ ( value ) => updateMeta( '_wpdr_note', value ) }
				rows={ 4 }
			/>
		</PluginDocumentSettingPanel>
	);
}

registerPlugin( 'wpdr-article-settings', {
	render: ArticleSettingsPanel,
} );
  • useSelect でエディターのストア(core/editor)から、編集中の投稿タイプとメタを読みます。getEditedPostAttribute( 'meta' ) は、保存前の変更も含んだ値を返します
  • useDispatch で取り出した editPost() にメタを渡すと、エディター上の値が変わります。データベースに書き込まれるのは、「更新」や「公開」で投稿を保存したときです
  • 読了時間の欄は、空にしたときに NaN を送らないよう、parseInt( value, 10 ) || 0 で数値にしています
  • __nextHasNoMarginBottom と __next40pxDefaultSize は、コンポーネントの新しい余白と高さを使う指定です。付けないと、ブラウザのコンソールに非推奨の警告が出ることがあります

パネルは、設定サイドバーの「投稿」タブの中に表示されます。表示されない場合は、エディター右上の「︙」メニューの「設定」で、パネルの表示がオフになっていないか確認します。

手順4: 独立したサイドバーを作る(PluginSidebar)

src/sidebar.js を作ります。index.js の import './sidebar'; で読み込まれるので、ビルドの設定を変える必要はありません。

import { registerPlugin } from '@wordpress/plugins';
import {
	PluginSidebar,
	PluginSidebarMoreMenuItem,
	store as editorStore,
} from '@wordpress/editor';
import { useSelect } from '@wordpress/data';
import { PanelBody, Notice } from '@wordpress/components';
import { count } from '@wordpress/wordcount';
import { __ } from '@wordpress/i18n';

function StatsSidebar() {
	const { title, content } = useSelect( ( select ) => {
		const { getEditedPostAttribute, getEditedPostContent } =
			select( editorStore );
		return {
			title: getEditedPostAttribute( 'title' ) || '',
			content: getEditedPostContent() || '',
		};
	}, [] );

	const titleLength = title.length;
	const chars = count( content, 'characters_excluding_spaces' );

	return (
		<>
			<PluginSidebarMoreMenuItem target="wpdr-stats" icon="chart-bar">
				{ __( '記事の統計', 'wpdr-editor-panel' ) }
			</PluginSidebarMoreMenuItem>
			<PluginSidebar
				name="wpdr-stats"
				title={ __( '記事の統計', 'wpdr-editor-panel' ) }
				icon="chart-bar"
			>
				<PanelBody title={ __( 'タイトル', 'wpdr-editor-panel' ) }>
					<p>
						{ __( '文字数:', 'wpdr-editor-panel' ) } { titleLength }
					</p>
					{ titleLength > 60 && (
						<Notice status="warning" isDismissible={ false }>
							{ __(
								'タイトルが60文字を超えています。',
								'wpdr-editor-panel'
							) }
						</Notice>
					) }
				</PanelBody>
				<PanelBody title={ __( '本文', 'wpdr-editor-panel' ) }>
					<p>
						{ __( '文字数(空白を除く):', 'wpdr-editor-panel' ) }{ ' ' }
						{ chars }
					</p>
				</PanelBody>
			</PluginSidebar>
		</>
	);
}

registerPlugin( 'wpdr-stats', {
	render: StatsSidebar,
} );
  • PluginSidebar を登録すると、エディター上部のツールバーにアイコン(ここでは chart-bar)が出て、クリックするとサイドバーが開きます
  • PluginSidebarMoreMenuItem は、「︙」メニューにも同じサイドバーを開く項目を加えます。target には PluginSidebar の name を指定します
  • 本文の文字数は、WordPress 本体の @wordpress/wordcount で数えています。HTML タグを除いて数えるので、ブロックのコメントやタグが文字数に入りません。単語の区切りに空白を使わない日本語では、単語数ではなく文字数を使います

手順5: ビルドして有効化する

npm run build

build/index.js と build/index.asset.php ができたら、「プラグイン」画面で「WPDR Editor Panel」を有効化し、投稿の編集画面を開きます。開発中は npm run start を実行しておくと、ファイルを保存するたびに自動でビルドされます(ブラウザは再読み込みが必要です)。

本番サーバーに置くときは、build フォルダーと PHP ファイルがあれば動きます。node_modules はアップロードしなくてかまいません。

メタが保存されたか確かめる

投稿を保存したあと、WP-CLI で値を確認できます(123 は投稿ID)。

wp post meta get 123 _wpdr_reading_time

うまくいかないとき

症状 確認すること
パネルもサイドバーも表示されない build/index.js があるか。ブラウザの開発者ツールのコンソールにエラーが出ていないか
WordPress 6.5 以前でコンソールにエラーが出る 6.6 より古いと、@wordpress/editor に PluginSidebar などがない。WordPress を更新する
入力しても保存されない register_post_meta() の show_in_rest と auth_callback、投稿タイプの custom-fields サポートを確認する
保存時にエラーが表示される メタの type と送っている値の型が合っているか
設定パネルが見当たらない 「︙」メニューの「設定」で非表示になっていないか。投稿タイプが post 以外なら、コードの判定を変える

まとめ

  • register_post_meta() で show_in_rest を有効にし、_ で始まるキーには auth_callback を付ける
  • enqueue_block_editor_assets で、build/index.asset.php の依存関係を使ってスクリプトを読み込む
  • 投稿の設定は PluginDocumentSettingPanel、独立した画面は PluginSidebar を使い、どちらも @wordpress/editor から読み込む
  • 値は useSelect で読み、useDispatch( editorStore ).editPost() で変更する。保存は投稿の保存と同時に行われる

関連記事:

お気軽にご相談ください

お見積りへ お問い合わせへ
▲