WordPress 命令面板 API 入门:注册静态命令

WordPress 6.3 引入命令面板,同时提供了让开发者扩展命令的 API。在 Mac 上按 Cmd + K、在 Windows 上按 Ctrl + K,便可打开面板,输入并搜索命令。

图 1:站点编辑器上方打开命令面板,展示可以搜索、执行的命令。原教学图见官方图片。

原教程发表于2023年11月20日。以下界面与 API 范围描述针对 WordPress 6.4:当时命令面板仅在文章编辑器和站点编辑器中提供,作者预期未来可能扩展到整个后台。这不是对当前版本覆盖范围的保证。6.4 对界面作了改进,也增加了内置命令,例如:

  • 新增文章或页面;
  • 编辑已有文章或页面;
  • 打开样板库;
  • 切换用户偏好。

这些是通过键盘浏览 WordPress 界面的基础命令。命令面板 API 还允许开发者用少量 JavaScript 添加自定义命令。可注册的命令分为静态命令和动态命令。本文讲解静态命令;动态命令及命令加载器见命令面板 API 开发说明。

前置知识

虽然本文介绍 API 的基础用法,但仍属于进阶教程。开始前,应熟悉 @wordpress/scripts以及通过它的 start、build 命令处理 JavaScript。

自定义命令通常通过插件添加,也可以通过主题添加。在主题中配置 @wordpress/scripts的方法,见Beyond block styles, part 1。

阅读 @wordpress/commands 文档有助于理解后面的代码,但不是开始本教程的必要条件。

注册静态命令

注册静态命令有两种方式:

  • wp.data.dispatch( wp.commands.store ).registerCommand() action;
  • wp.commands.useCommand() React hook。

两者接受相同参数,主要区别是 useCommand() 必须在 React 组件内部使用;组件外应使用 registerCommand()。它们都接受一个对象,可设置以下属性:

  • name:命令唯一的命名空间与 slug。
  • label:在命令面板中显示的标签。
  • searchLabel:可选,用于匹配用户搜索内容;面板实际显示的仍是 label。
  • context:可选,让命令出现在特定界面的默认命令列表。原教程列出 site-editor(站点编辑器主界面)和 site-editor-edit(在站点编辑器中编辑模板)。
  • icon:显示在标签旁的 SVG 图标,以 React 组件提供。
  • callback:用户选择命令时执行的回调。

下面是 registerCommand() 的调用形式:

wp.data.dispatch( wp.commands.store ).registerCommand( {
	name:  'your-namespace/your-command-slug',
	label: 'Command label',
	searchLabel: 'Command search label',
	icon:  icon,
	context: 'site-editor',
	callback: ( { close } ) => {
		close();
	}
} );

熟悉 WordPress JavaScript 的开发者通常能直接理解这些属性。主要需要决定的是 callback 执行什么操作,这就是命令本身的行为。

构建一个示例命令插件

接下来按原教程构建一个添加自定义命令的插件。

设置插件

在 WordPress 安装目录的 wp-content/plugins 中新建插件,文件结构如下:

  • build/:保存 WordPress 工具编译出的文件。
  • src/index.js:JavaScript 源文件。
  • index.php:插件入口。
  • package.json:包与脚本配置。

在 package.json 中至少定义 start 和 build:

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

通过 CLI 安装 @wordpress/scripts:

npm install @wordpress/scripts --saveDev

还需要安装 @wordpress/icons:

npm install @wordpress/icons

接着在 index.php 中加入插件文件头,例如:

<?php
/**
 * Plugin Name:       Dev Blog: Command Palette API
 * Plugin URI:        https://developer.wordpress.org/news/
 * Description:       Showcases examples of adding static commands via the Command Palette API.
 * Version:           1.0.0
 * Requires at least: 6.4
 * Requires PHP:      7.4
 * Author:            WordPress Developer Blog
 * Author URI:        https://developer.wordpress.org/news/
 * Text Domain:       dev-blog
 */

启用示例插件后,运行开发构建命令:

npm run start

加载编辑器脚本

这里没有注册自定义区块,WordPress 不会自动加载 JavaScript,因此需要主动加载 build/index.js。原文说明段写的是 enqueue_block_editor_scripts,但紧随其后的代码实际使用 enqueue_block_editor_assets。下面保留原始代码,并明确这一原文差异,避免把不同名称混为同一个 hook。

在插件的 index.php 中加入:

add_action( 'enqueue_block_editor_assets', 'devblog_command_api_editor_assets' );

function devblog_command_api_editor_assets() {
	$asset_file = trailingslashit( __DIR__ ) . 'build/index.asset.php';

	if ( file_exists( $asset_file ) ) {
		$asset = include $asset_file;

		wp_enqueue_script(
			'devblog-command-api',
			trailingslashit( plugin_dir_url( __FILE__ ) ) . 'build/index.js',
			$asset['dependencies'],
			$asset['version'],
			true
		);
	}
}

导入依赖

打开 src/index.js,准备导入注册命令所需的依赖:@wordpress/commands、@wordpress/data、@wordpress/i18n 和 @wordpress/icons。

在文件顶部添加:

import { store as commandsStore } from '@wordpress/commands';
import { dispatch } from '@wordpress/data';
import { __ } from '@wordpress/i18n';
import { settings, comment, button } from '@wordpress/icons';

现在可以尝试以下命令示例。

示例 1:跳转到后台页面

先添加一个跳转到 WordPress 后台其他页面的命令。

图 2:站点编辑器的命令面板中搜索 “gutenberg”,结果列表包含 Gutenberg Experiments。原教学图见官方图片。

原作者选择的是 Gutenberg Experiments 设置界面,需要启用 Gutenberg 插件。也可以将代码中的 URL 改成其他目标页面。

跳转通过设置 JavaScript document.location 对象的 href 属性完成。在 src/index.js 中添加:

dispatch( commandsStore ).registerCommand( {
	name:  'dev-blog/gutenberg-experiments',
	label: __( 'Gutenberg Experiments', 'dev-blog' ),
	icon:  settings,
	context: 'site-editor',
	callback: ( { close } ) => {
		document.location.href = 'admin.php?page=gutenberg-experiments';
		close();
	}
} );

测试时,打开命令面板并输入 “Gutenberg Experiments”。按原教程预期,命令会出现在结果中,选择后应跳转到相应后台界面。

示例 2:切换编辑器面板

这个命令用于启用或禁用文章编辑器中的“讨论”面板。

图 3:文章编辑器的命令面板中搜索切换讨论面板的命令。原教学图见官方图片。

只要知道面板名称,也可以切换其他面板。“讨论”面板的名称是 discussion-panel。将名称传给 core/edit-post 的 toggleEditorPanelEnabled() action 即可。

在 src/index.js 中添加:

dispatch( commandsStore ).registerCommand( {
	name:  'dev-blog/discussion-panel',
	label: __( 'Toggle discussion panel', 'dev-blog' ),
	icon:  comment,
	callback: ( { close } ) => {
		dispatch( 'core/edit-post' ).toggleEditorPanelEnabled(
			'discussion-panel'
		);
		close();
	}
} );

并非每个编辑器都有相同面板。例如,讨论面板存在于文章编辑器,但不在站点编辑器中显示。因此在站点编辑器执行这个命令,看不到相应结果。

原作者没有认定这种体验最佳。另一种选择是仅在文章编辑界面注册命令:检查 wp.editPost 是否已定义,然后将上述代码包进条件判断:

if ( undefined !== wp.editPost ) {
	dispatch( commandsStore ).registerCommand( {
		name:  'dev-blog/discussion-panel',
		label: __( 'Toggle discussion panel', 'dev-blog' ),
		icon:  comment,
		callback: ( { close } ) => {
			dispatch( 'core/edit-post' ).toggleEditorPanelEnabled(
				'discussion-panel'
			);
			close();
		}
	} );
}

原作者对条件式命令是否改善体验也持开放态度,并邀请读者讨论如何处理。

示例 3:切换用户偏好

再添加一个命令,切换编辑器界面按钮显示图标还是文字标签。

图 4:站点编辑器正在编辑单篇文章模板,命令面板中搜索切换按钮标签的命令。原教学图见官方图片。

这个例子也依赖编辑器上下文。用户偏好分别按站点编辑器和文章编辑器保存。

检查 wp.editPost 可判断是否在文章编辑器;站点编辑器对应的对象是 wp.editSite。切换偏好使用 core/preferences 数据模块的 toggle() action,需要提供编辑器名称(core/edit-site 或 core/edit-post)和偏好名称。这里要切换的是 showIconLabels。

将以下代码加入 src/index.js:

dispatch( commandsStore ).registerCommand( {
	name:  'dev-blog/toggle-button-labels',
	label: __( 'Toggle button labels', 'dev-blog' ),
	icon:  button,
	context: 'site-editor-edit',
	callback: ( { close } ) => {
		
		// Toggles preference for site editor.
		if ( undefined !== wp.editSite ) {
			dispatch( 'core/preferences' ).toggle(
				'core/edit-site',
				'showIconLabels'
			);
		}

		// Toggles preference for post editor.
		else if ( undefined !== wp.editPost ) {
			dispatch( 'core/preferences' ).toggle(
				'core/edit-post',
				'showIconLabels'
			);
		}

		close();
	}
} );

是否使用条件判断由开发者决定。也可以不论当前在哪个编辑器,都同时切换两者的偏好。这样仍需要两次 dispatch( 'core/preferences' ).toggle() 调用,只是移除包在外面的条件判断。

示例 4:在组件内部注册命令

前面的命令从组件外注册,但插件中经常需要在组件内部工作。这里进一步改进示例 2:把命令放进组件,根据面板当前状态显示不同标签,并在状态改变时于左下角显示 snackbar 通知。

图 5:文章编辑器中显示讨论面板的条件式命令;状态改变时出现通知。原教学图见官方图片。

先更新导入:从 @wordpress/commands 导入 useCommand,从 @wordpress/data 导入 useDispatch 与 useSelect,并导入 registerPlugin。**原文项目列表将后者误写成 @wordpress/buttons,实际代码来自 @wordpress/plugins。**以下仍保留原始代码。

将 index.js 的导入改成:

import { store, useCommand } from '@wordpress/commands';
import { dispatch, useDispatch, useSelect } from '@wordpress/data';
import { __ } from '@wordpress/i18n';
import { settings, search, comment, button } from '@wordpress/icons';
import { registerPlugin } from '@wordpress/plugins';

注意:这一示例把 commands store 导入为 store,而前面示例用的是 commandsStore 别名。若把多个示例合并为同一文件,需要自行统一引用;原教程没有提供合并后的完整文件。

接着添加:

if ( undefined !== wp.editPost ) {
	registerPlugin( 'dev-blog-command-palette', {
		render: () => {
			// Determine if the discussion panel is enabled.
			const discussionPanelEnabled = useSelect( ( select ) => {
				return select( 'core/edit-post' ).isEditorPanelEnabled( 
					'discussion-panel' 
				);
			}, [] );

			// Get functions for toggling panels and creating snackbars.
			const { toggleEditorPanelEnabled } = useDispatch( 'core/edit-post' );
			const { createInfoNotice }         = useDispatch( 'core/notices'   );

			// Register command to toggle discussion panel.
			useCommand( {
				name:  'dev-blog/discussion-show-hide',
				label: discussionPanelEnabled
				       ? __( 'Hide discussion panel', 'dev-blog' ) 
				       : __( 'Show discussion panel', 'dev-blog' ),
				icon:  comment,
				callback: ( { close } ) => {
					// Toggle the discussion panel.
					toggleEditorPanelEnabled( 'discussion-panel' );
					
					// Add a snackbar notice.
					createInfoNotice(
						discussionPanelEnabled
						? __( 'Discussion panel hidden.', 'dev-blog' )
						: __( 'Discussion panel displayed.', 'dev-blog' ),
						{
							id:   'dev-blog/toggle-discussion/notice',
							type: 'snackbar'
						}
					);
		
					close();
				}
			} );
		}
	} );
}

这些函数与 hook 分工如下:

这些例子提供了开始使用命令面板 API 所需的基础。原作者也邀请开发者分享计划构建的功能。

来源与许可

原文:Getting started with the Command Palette API,作者 Justin Tadlock,发表于2023年11月20日。原文感谢 @dansoschin、@bph、@juanmaguitar 和 @richtabor 提供反馈与审阅。中文稿于2026-10-03按原文正文整理,并标明历史版本范围和原文不一致处。

按照 WordPress Documentation Licensing,覆盖 developer.wordpress.org/ 的文档文字和图片按 CC0提供,示例代码按 GNU GPL v2 或更新版本提供。代码未修改;完整 GPL v2 许可见官方许可全文。正式分发代码时应同时提供该许可文本。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容