gutenbergdocs/docs/how-to-guides/plugin-sidebar-0.md
2025-10-22 01:40:18 +08:00

14 KiB
Raw Permalink Blame History

步骤三:注册元字段

若要在 post_meta 表中操作字段,请使用 register_post_meta 函数创建名为 sidebar_plugin_meta_block_field 的新字段。

注意:此字段需对 REST API 可用,因为区块编辑器通过该接口访问数据。

将以下 PHP 代码添加到插件的 init 回调函数中:

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,请确保文章类型支持 custom-fields。可通过注册文章类型时设置,或使用 add_post_type_support 函数实现。

步骤四:初始化输入控件

当字段在编辑器存储中就绪后,即可将其呈现在用户界面中。我们将输入控件提取为独立函数以保持代码整洁,便于后续功能扩展。

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

	var MetaBlockField = function () {
		return el( TextControl, {
			label: '元区块字段',
			value: '初始值',
			onChange: function ( content ) {
				console.log( '内容已更改为 ', content );
			},
		} );
	};

	registerPlugin( 'my-plugin-sidebar', {
		render: function () {
			return el(
				PluginSidebar,
				{
					name: 'my-plugin-sidebar',
					icon: 'admin-post',
					title: '我的插件侧边栏',
				},
				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.editor.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: '元区块字段',
			value: metaFieldValue,
			onChange: function ( content ) {
				console.log( '内容已更改为 ', content );
			},
		} );
	};

	registerPlugin( 'my-plugin-sidebar', {
		render: function () {
			return el(
				PluginSidebar,
				{
					name: 'my-plugin-sidebar',
					icon: 'admin-post',
					title: '我的插件侧边栏',
				},
				el(
					'div',
					{ className: 'plugin-sidebar-content' },
					el( MetaBlockField )
				)
			);
		},
	} );
} )( window.wp );

wp.data.useSelect 函数来自 @wordpress/data 包,因此需要在 PHP 的 wp_register_script 函数中将 wp-data 添加为依赖项。

注意:getEditedPostAttribute 调用用于获取文章的最新值,包括用户尚未保存的编辑内容。

更新代码后重新加载并打开侧边栏即可验证功能。此时输入框内容不再是「初始值」而显示为空字符串。虽然用户暂时还无法输入值,但可以验证当存储中的值发生变化时组件是否会更新。打开浏览器控制台执行:

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

即可观察到输入组件中的内容实时更新。

步骤5在输入内容变化时更新元字段

最后一步是在输入内容发生变化时更新元字段。 useDispatch 函数接收一个存储名称作为唯一参数,并返回可用于更新存储的方法,这里我们将使用 editPost

( function ( wp ) {
	var el = React.createElement;
	var registerPlugin = wp.plugins.registerPlugin;
	var PluginSidebar = wp.editor.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: '元区块字段',
			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: '我的插件侧边栏',
				},
				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'
];

显示的消息应该是您在输入框中输入的内容。

在保存文章时,您可以通过保存后重新加载页面并确认输入控件已初始化为您最后输入的值,来验证内容是否正确存储到数据库中。

附加资源

有关使用 @wordpress/data 包 的文档。

本指南中使用的函数:

总结

您现在拥有一个自定义侧边栏,可用于更新 post_meta 内容。

完整示例可在 block-development-examples 代码库中下载 plugin-sidebar 示例

注意

如果您在编辑器“偏好设置”的“面板”页面中启用了“自定义字段”(通过右上角的三个点),与 TextControl 同名的字段(在本例中为 sidebar_plugin_meta_block_field)也会出现在编辑器窗口底部的自定义字段面板中。这两个字段可以访问相同的元属性。

文本控件与自定义字段

在保存文章时TextControl 中的值会先保存,而自定义字段中的值会后保存,因此最终保存到数据库的是自定义字段中的值。因此,如果您更改了 TextControl 中的值,最终保存的仍然是自定义字段中的值。

如果未启用自定义字段,则不会出现此问题。

如果您需要启用自定义字段并在侧边栏中显示文章元数据,有两种可能的解决方案:

  1. 在元字段名称前添加下划线,例如上述示例中的名称改为 _sidebar_plugin_meta_block_field。这表示该文章元数据应视为私有,不会在文章的自定义字段部分显示。使用此解决方案时,除非您在传递给 register_post_metaargs 数组中添加一个 auth_callback 属性,并提供一个最终返回 true 的函数,否则在保存文章时会生成错误。有关更多信息,请参阅 post_meta 页面中的 args 文档。
  2. 在 TextControl 的 onChange 函数中,将目标指向值字段的文本区域,并将其值设置为与 TextControl 元字段中的值相同。这样,两个位置的值将保持一致,因此您可以确保即使更改了 TextControl 中的值,它仍然会被保存到数据库中。
return el( TextControl, {
  label: '元区块字段',
  value: metaFieldValue,
  onChange: function ( content ) {
    editPost( {
      meta: { sidebar_plugin_meta_block_field: content }
    })
    document.querySelector( {值字段文本区域} ).innerHTML = content;
  },
} );

插件侧边栏

概述

如何为插件添加侧边栏。侧边栏位于编辑器最右侧区域。您的插件可以在检查器控件(齿轮图标)旁添加额外图标,该图标可展开显示。

侧边栏示例

注意:本教程主要讲解自定义侧边栏,如需在侧边栏添加控件请参阅区块工具栏与设置侧边栏

准备工作

本教程假设您已具备插件基础环境并准备添加PHP和JavaScript代码。请先参阅JavaScript入门指南了解WordPress插件基础知识及如何使用JavaScript扩展区块编辑器。

分步指南

步骤1启动侧边栏

首先需要告知编辑器存在包含独立侧边栏的新插件。请分别使用@wordpress/plugins@wordpress/editorreact包提供的registerPluginPluginSidebarcreateElement工具。

将以下代码添加至名为plugin-sidebar.js的JavaScript文件并保存到插件目录

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

	registerPlugin( 'my-plugin-sidebar', {
		render: function () {
			return el(
				PluginSidebar,
				{
					name: 'my-plugin-sidebar',
					icon: 'admin-post',
					title: '我的插件侧边栏',
				},
				'元字段'
			);
		},
	} );
} )( window.wp, window.React );

为使代码正常运行,需确保这些工具在浏览器中可用,因此必须将wp-pluginswp-editorreact指定为脚本依赖项。

以下是注册脚本并声明依赖项的PHP代码

<?php

/*
插件名称:侧边栏插件
*/

function sidebar_plugin_register() {
	wp_register_script(
		'plugin-sidebar-js',
		plugins_url( 'plugin-sidebar.js', __FILE__ ),
		array( 'wp-plugins', 'wp-editor', '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' );

安装并启用此插件后,编辑器右上角将出现新的图钉图标。点击即可展开插件侧边栏:

运行中的侧边栏

步骤2调整样式并添加控件

侧边栏运行后,接下来需要填充必要组件和基础样式。

为可视化编辑元字段值,将使用输入组件。@wordpress/components包提供多种可复用组件,其中TextControl专用于创建输入字段:

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

	registerPlugin( 'my-plugin-sidebar', {
		render: function () {
			return el(
				PluginSidebar,
				{
					name: 'my-plugin-sidebar',
					icon: 'admin-post',
					title: '我的插件侧边栏',
				},
				el(
					'div',
					{ className: 'plugin-sidebar-content' },
					el( TextControl, {
						label: '元区块字段',
						value: '初始值',
						onChange: function ( content ) {
							console.log( '内容已更改为 ', content );
						},
					} )
				)
			);
		},
	} );
} )( window.wp );

使用新代码更新plugin-sidebar.js。注意代码使用了@wordpress/components包中的wp.components工具请确保在PHP文件的wp_register_script函数中添加wp-components依赖项。

代码新增内容:

  • div元素添加CSS类plugin-sidebar-content用于样式定位
  • 使用TextControl组件替代纯文本'元字段'

通过新增的CSS类可添加基础样式。在插件目录创建plugin-sidebar.css文件并添加内边距设置:

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

注册样式表并通过enqueue_block_editor_assets与JavaScript文件同时加载。

完成修改后PHP代码如下所示

<?php

/*
插件名称:侧边栏示例
*/

function sidebar_plugin_register() {
	wp_register_script(
		'plugin-sidebar-js',
		plugins_url( 'plugin-sidebar.js', __FILE__ ),
		array(
			'react',
			'wp-plugins',
			'wp-editor',
			'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' );

重新加载编辑器并打开侧边栏:

含样式和控件的侧边栏

当前代码尚未实现数据存储与检索功能,后续步骤将重点介绍如何连接元区块字段。