命令面板 API 入门指南
WordPress 6.3 向数百万用户引入了命令面板,并提供了一个API 供开发者扩展其功能,添加额外的命令。
这类功能在其他应用和程序中很常见。在 WordPress 中,你可以按 Mac 上的 Cmd + K 或 Windows 上的 Ctrl + K,屏幕上会出现一个模态框。然后,只需输入或搜索命令:
截至 WordPress 6.4,命令面板仅在文章编辑器和站点编辑器屏幕中可用。在未来的版本中,它很可能成为整个管理区域的功能。
版本 6.4 优化了界面,并向其内置命令目录添加了更多选项。一些现有命令允许你:
- 添加新文章/页面
- 编辑现有文章/页面
- 访问模式库
- 切换各种用户偏好设置
这些只是你期望通过键盘导航 WordPress 界面的一些基础命令。但让命令面板真正强大的是 API,它允许你用最少的 JavaScript 代码添加自定义命令。
你可以注册两种类型的命令:静态命令和动态命令。在本教程中,你将学习如何注册静态命令,但你可以在命令面板 API 的开发说明中了解更多关于动态命令(命令加载器)的信息。
先决条件
虽然你将在本文中学习命令面板 API 的基础知识,但这仍然是一个高级教程。这意味着在继续之前,你应该熟悉使用 @wordpress/scripts 包。本教程期望你了解如何运行该包中的 start 和 build 命令来处理所需的 JavaScript 代码。
你很可能通过插件添加自定义命令。但是,也可以通过主题添加。要了解如何在主题中设置 @wordpress/scripts,请查看超越区块样式,第 1 部分:在主题中使用 WordPress 脚本包。
查阅 @wordpress/commands 文档将加深你对后续代码的理解,但开始阅读本文并非必需。
注册静态命令
有两种注册静态命令的方法:
wp.data.dispatch( wp.commands.store ).registerCommand()操作wp.commands.useCommand()React Hook
它们本质上工作方式相同,接受相同的参数。唯一的区别是 useCommand() Hook 必须在 React 组件内部使用。在组件外部,请使用 registerCommand()。两者都接受一个对象参数,允许你定义几个属性:
name: 命令的唯一命名空间和别名。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
index.phppackage.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
*/
激活示例插件后,别忘了运行 start CLI 命令:
npm run start
加载编辑器脚本
因为这不是一个自定义区块,WordPress 不会自动加载你的 JavaScript,你需要在 enqueue_block_editor_scripts Hook 上加载你的 build/index.js 文件。
将此代码添加到你的插件 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 文件。你将用它来导入添加命令所需的依赖项:
要导入依赖项,请将此添加到你的 src/index.js 文件顶部:
import { store as commandsStore } from '@wordpress/commands';
import { dispatch } from '@wordpress/data';
import { __ } from '@wordpress/i18n';
import { settings, comment, button } from '@wordpress/icons';
现在你可以开始使用命令面板 API 了。尝试以下一些示例。
示例 #1:导航到管理页面命令
对于第一个示例,让我们添加一个简单的命令来访问 WordPress 管理后台的其他页面,如下所示:
我选择了一个用于导航到Gutenberg 实验设置屏幕的命令(需要 Gutenberg 插件处于活动状态)。但你可以将下面代码中的 URL 更改为指向你想要的任何网页。
要添加一个导航到另一个页面的命令,你可以使用 document.location JavaScript 对象并设置其 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:切换面板命令
在这个示例中,你将添加一个切换命令,用于启用或禁用文章编辑器中的讨论面板:
只要你知道面板的名称,就可以对任何面板执行此操作。对于讨论面板,它是 discussion-panel。
要切换文章编辑器中的面板,你需要将面板名称传递给来自 core/edit-post 的 toggleEditorPanelEnabled() 操作。
将此代码添加到你的 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:切换用户偏好命令
对于最后一个示例,让我们构建一个命令来切换用户偏好,在编辑器 UI 按钮的图标或标签之间切换:
这是另一个类似于前一个示例的上下文相关命令。不同之处在于,偏好设置是根据当前编辑器存储的。一个用于站点编辑器,一个用于文章编辑器。
你已经知道如何检查 wp.editPost 来确定你是否在文章编辑器中。有一个等效的对象用于检查站点编辑器:wp.editSite。
要切换用户偏好,请使用来自 core/preferences 数据模块的 toggle() 操作。你需要知道编辑器名称(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 通知消息来改善用户体验:
首先,你需要更新导入以包含其他一些项目:
- 来自
@wordpress/commands包的useCommand。 - 来自
@wordpress/data包的useDispatch和useSelect。 - 来自
@wordpress/buttons包的registerPlugin。
更新 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';
现在将此代码添加到你的 index.js 文件中:
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();
}
} );
}
} );
}
这些代码的许多内容可能与之前的示例不同。以下是每个函数或钩子调用的简要说明:
registerPlugin():用作渲染组件的包装器。
useCommand():注册显示或隐藏讨论面板的命令。
useSelect():从存储中选择数据:core/edit-post
isEditorPanelEnabled():决定讨论小组是否启用。
useDispatch():从和得到作用函数:core/edit-postcore/notices
toggleEditorPanelEnabled():切换讨论面板。
createInfoNotice():制造小吃吧的广告。
现在你应该拥有了开始使用命令调色板API所需的一切。我很想听听你想用它做什么,欢迎在评论区分享你的想法。