Gutenberg 的 PluginBlockSettingsMenuItem 插槽指南:为块设置菜单(More Options)注入自定义菜单项
2026/9/16 10:39:28 网站建设 项目流程

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 参考列表中,它与其他插槽(如PluginBlockSettingsMenuGroupPluginDocumentSettingPanel)并列,是扩展块编辑体验的标准入口之一。

Props 详解

根据官方文档 packages/editor/README.md 的参数说明与源码 plugin-block-settings-menu-item.jsx 的 JSDoc,该组件接受以下属性:

属性类型必填说明
allowedBlocksArray块名称(Block Name)数组,指定菜单项仅在哪些块上显示。不传则对所有块显示。多选块时,仅当所有选中块的类型都在该列表中才显示(不要求是同一个块)。
iconWPBlockTypeIconRender菜单项图标。可以是 Dashicon 的 slug 字符串(如'smiley'),也可以是一个 SVG WP 元素。
labelstring菜单项文本。
onClickFunction用户点击菜单项时执行的回调函数。
smallboolean是否渲染 label 文本。true时 label 作为MenuItemlabel属性传入(配合noIcons场景下的紧凑布局),false(默认)时 label 作为菜单项的子文本渲染。
rolestring菜单项的 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-editorBlockSettingsMenuControls(源码第 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 的过滤逻辑

源码中shouldRenderItemisEverySelectedBlockAllowed两段辅助函数(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 )获取当前选中块的名称数组,并随canEditselectedClientIds一起下发。

3. 点击后自动关闭菜单

onClickcompose( onClick, onClose )包裹(源码第 93 行),即点击你的菜单项后,块设置菜单会自动关闭,无需在回调里手动处理。onCloseBlockSettingsDropdown在下拉菜单打开时注入——见 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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询