Gutenberg 的 PluginBlockSettingsMenuItem 插槽指南:为块设置菜单(More Options)注入自定义菜单项
【免费下载链接】gutenbergThe Block Editor project for WordPress and beyond. Plugin is available from the official repository.项目地址: https://gitcode.com/GitHub_Trending/gu/gutenberg
PluginBlockSettingsMenuItem 是 Gutenberg 块编辑器(@wordpress/editor)提供的一个 SlotFill 插槽,允许插件开发者向选中块的「更多选项」(More Options)菜单中注入自定义菜单项。本文围绕官方参考文档 plugin-block-settings-menu-item.md 展开,结合仓库内 plugin-block-settings-menu-item.jsx 的源码实现,完整讲解它的位置、全部 Props、可复制运行的示例代码,以及底层的渲染与过滤逻辑,帮助你在不修改核心代码的前提下扩展块级操作入口。
这个插槽是什么
PluginBlockSettingsMenuItem 是一个「块设置菜单项」插槽。它把插件自定义的菜单项渲染进每个块的操作菜单(即选中块后工具栏上的「更多选项 / Options」三圆点下拉菜单)中。
它的两个关键特性:
- 位置随用户设置变化:菜单项会出现在每个块的控件菜单中,或出现在**顶部工具栏(Top Toolbar)**中,具体取决于用户的界面设置(参考文档原文:"This will either appear in the controls for each block or at the Top Toolbar depending on the users setting")。即开启「统一工具条(Unified toolbar)」偏好时,块操作菜单会收拢到顶部工具栏,你的菜单项也随之移动,无需插件做任何额外适配。
- 按块类型定向显示:通过
allowedBlocks属性,你可以让菜单项只出现在指定块(如仅core/paragraph)的菜单中,实现精准的上下文注入。
在 docs/reference-guides/slotfills/README.md 的 SlotFills 参考列表中,它与其他插槽(如PluginBlockSettingsMenuGroup、PluginDocumentSettingPanel)并列,是扩展块编辑体验的标准入口之一。
Props 详解
根据官方文档 packages/editor/README.md 的参数说明与源码 plugin-block-settings-menu-item.jsx 的 JSDoc,该组件接受以下属性:
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
allowedBlocks | Array | 否 | 块名称(Block Name)数组,指定菜单项仅在哪些块上显示。不传则对所有块显示。多选块时,仅当所有选中块的类型都在该列表中才显示(不要求是同一个块)。 |
icon | WPBlockTypeIconRender | 否 | 菜单项图标。可以是 Dashicon 的 slug 字符串(如'smiley'),也可以是一个 SVG WP 元素。 |
label | string | 是 | 菜单项文本。 |
onClick | Function | 是 | 用户点击菜单项时执行的回调函数。 |
small | boolean | 否 | 是否渲染 label 文本。true时 label 作为MenuItem的label属性传入(配合noIcons场景下的紧凑布局),false(默认)时 label 作为菜单项的子文本渲染。 |
role | string | 否 | 菜单项的 ARIA role,用于无障碍访问语义定制。 |
完整示例(ESNext,可直接复制运行)
继承参考文档的官方示例(plugin-block-settings-menu-item.md),并补充国际化与注释,使其可直接放进插件的入口 JS 文件:
import { registerPlugin } from '@wordpress/plugins'; import { PluginBlockSettingsMenuItem } from '@wordpress/editor'; import { __ } from '@wordpress/i18n'; const PluginBlockSettingsMenuGroupTest = () => ( <PluginBlockSettingsMenuItem allowedBlocks={ [ 'core/paragraph' ] } icon="smiley" label={ __( 'Menu item text', 'my-plugin' ) } onClick={ () => { alert( 'clicked' ); } } /> ); registerPlugin( 'block-settings-menu-group-test', { render: PluginBlockSettingsMenuGroupTest, } );关键点:
registerPlugin来自@wordpress/plugins,插件必须通过它注册,组件才会被挂载进编辑器。PluginBlockSettingsMenuItem从@wordpress/editor导入(它由 packages/editor/src/components/index.js 统一导出)。- 上面的
label使用__()做国际化(非官方示例必需,但属于插件开发最佳实践)。
点击后菜单会自动关闭,因为源码中使用compose( onClick, onClose )将你的回调与关闭菜单的onClose组合在一起(详见下文原理分析),所以你只需关注自己的业务逻辑。
ES5 传统写法(不使用构建工具时)
如果插件不经过 Webpack/Babel 构建,可以使用wp.editor全局变量以 ES5 方式实现同样的效果(官方文档 packages/editor/README.md 提供了该写法):
var __ = wp.i18n.__; var PluginBlockSettingsMenuItem = wp.editor.PluginBlockSettingsMenuItem; function doOnClick() { // 用户点击菜单项时要执行的逻辑 } function MyPluginBlockSettingsMenuItem() { return React.createElement( PluginBlockSettingsMenuItem, { allowedBlocks: [ 'core/paragraph' ], icon: 'dashicon-name', label: __( 'Menu item text' ), onClick: doOnClick, } ); }底层实现原理
理解源码能帮你更准确地使用这个插槽。核心实现在 plugin-block-settings-menu-item.jsx 中,仅约 100 行,逻辑非常清晰。
1. 它本质上是 BlockSettingsMenuControls 的薄封装
组件内部导入了@wordpress/block-editor的BlockSettingsMenuControls(源码第 1 行),并以 render props 方式消费它:
<BlockSettingsMenuControls> { ( { selectedBlocks, onClose } ) => { if ( ! shouldRenderItem( selectedBlocks, allowedBlocks ) ) { return null; } return ( <MenuItem onClick={ compose( onClick, onClose ) } icon={ icon } label={ small ? label : undefined } role={ role }> { ! small && label } </MenuItem> ); } } </BlockSettingsMenuControls>从源码结构看,BlockSettingsMenuControls是更底层的插槽(Slot 定义在 packages/block-editor/src/components/block-settings-menu-controls/index.jsx 的createSlotFill( 'BlockSettingsMenuControls' )),它本身也承载了「转换为组 / 锁定 / 重命名 / 可见性」等核心菜单项。PluginBlockSettingsMenuItem相当于为插件开发者提供了「只添加一个菜单项」的便捷封装,而不必手动处理selectedBlocks判断和MenuItem组合。
2. allowedBlocks 的过滤逻辑
源码中shouldRenderItem与isEverySelectedBlockAllowed两段辅助函数(plugin-block-settings-menu-item.jsx)决定了菜单项的显隐:
const isEverySelectedBlockAllowed = ( selected, allowed ) => selected.filter( ( id ) => ! allowed.includes( id ) ).length === 0; const shouldRenderItem = ( selectedBlocks, allowedBlocks ) => ! Array.isArray( allowedBlocks ) || isEverySelectedBlockAllowed( selectedBlocks, allowedBlocks );- 未传入
allowedBlocks(即非数组)时,菜单项对所有块渲染; - 传入数组时,当前选中块列表中任意一个不在白名单内,菜单项就不渲染;
- 多选场景:当多个块被选中时,只有全部选中块的类型都属于白名单(允许是不同类型的块)才显示。
selectedBlocks来自BlockSettingsMenuControls的 Slot fillProps——在 block-settings-menu-controls/index.jsx 中通过getBlockNamesByClientId( ids )获取当前选中块的名称数组,并随canEdit、selectedClientIds一起下发。
3. 点击后自动关闭菜单
onClick被compose( onClick, onClose )包裹(源码第 93 行),即点击你的菜单项后,块设置菜单会自动关闭,无需在回调里手动处理。onClose由BlockSettingsDropdown在下拉菜单打开时注入——见 block-settings-dropdown.jsx,其中以fillProps={ { onClose, count, firstBlockClientId } }渲染BlockSettingsMenuControls.Slot。
4. 渲染位置与内容保护
从 block-settings-dropdown.jsx 与 block-settings-menu-controls/index.jsx 的代码可以看出,插槽填充(fills)仅在非contentOnly编辑模式(即非「仅内容编辑」的模板局部锁定状态)下渲染;同时它被放进MenuGroup中,与「转换为组、锁定、重命名」等核心菜单项同组显示,视觉上紧邻这些系统菜单项。
实战注意事项
- 国际化:
label建议用__()包裹,参考packages/editor包内其他组件的做法,避免硬编码文案。 - 图标选择:
icon传 Dashicon slug(如'smiley'、'star-filled')最简单;需要定制图形时也可直接传 SVG 元素。 - 不要把重型操作放 onClick 里:菜单项点击即触发且菜单随即关闭,适合「复制内容、跳转、开关设置」这类短操作;需要长流程交互时,建议改用
PluginBlockSettingsMenuGroup(可嵌入表单控件)或Modal组合方案。 - 与
PluginBlockSettingsMenuGroup的区别:PluginBlockSettingsMenuItem只负责渲染单个MenuItem;如果需要在同一组中放置多个控件(开关、输入框、分组菜单),应使用同目录下的其他 Group 类插槽,它们共享同一个BlockSettingsMenuControls底层槽位。
相关文件指引
- 官方参考文档:docs/reference-guides/slotfills/plugin-block-settings-menu-item.md
- 组件源码:packages/editor/src/components/block-settings-menu/plugin-block-settings-menu-item.jsx
- 导出声明:packages/editor/src/components/index.js
- API 文档(含参数表与双版本示例):packages/editor/README.md
- 底层插槽实现:packages/block-editor/src/components/block-settings-menu-controls/index.jsx
- 菜单挂载点:packages/block-editor/src/components/block-settings-menu/block-settings-dropdown.jsx
- SlotFills 索引:docs/reference-guides/slotfills/README.md
综上,PluginBlockSettingsMenuItem是向块级「更多选项」菜单注入操作入口的最轻量方案:一个registerPlugin加一个组件即完成接入,allowedBlocks负责精准定向,底层由BlockSettingsMenuControls插槽统一承载,且天然兼容用户对工具栏布局的偏好设置。
【免费下载链接】gutenbergThe Block Editor project for WordPress and beyond. Plugin is available from the official repository.项目地址: https://gitcode.com/GitHub_Trending/gu/gutenberg
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考