Gutenberg 编辑器 Hooks 全指南:使用 WordPress 过滤器与动作深度定制 Block Editor
【免费下载链接】gutenbergThe Block Editor project for WordPress and beyond. Plugin is available from the official repository.项目地址: https://gitcode.com/GitHub_Trending/gu/gutenberg
导读
WordPress 通过block_editor_settings_all等 PHP 过滤器、@wordpress/hooks的 JavaScript 过滤器/动作,以及 REST API 预加载路径过滤,向插件与主题作者开放了大量编辑体验定制点。本文以官方文档 editor-filters.md 为核心骨架,结合 Gutenberg 仓库源码,系统讲解从禁用代码编辑器、限制响应式编辑,到客户端媒体处理、错误边界日志上报的完整实现方案。读完本文,你将能精确控制编辑器的行为开关、按需裁剪功能入口,并将自己的逻辑无缝挂入编辑器的渲染管线。
认识编辑器设置过滤器:block_editor_settings_all
block_editor_settings_all是修改编辑器行为的最常用入口。它在编辑器初始化之前、设置项被发送到客户端之前被应用,让插件与主题作者对编辑器行为拥有广泛的控制权。该钩子向回调函数传递两个参数:
$settings—— 编辑器可配置设置的数组;$context——WP_Block_Editor_Context实例,包含当前编辑器的信息(如当前文章对象post、编辑器类型等)。
在 Gutenberg 仓库中,插件自身的核心设置也是通过该过滤器注入的:lib/block-editor-settings.php第 126 行以优先级0挂载gutenberg_get_block_editor_settings,用于替换 WordPress 核心的styles与__experimentalFeatures设置,并注明"该钩子应最先运行,因为它会完整替换核心设置"。这说明过滤器存在执行顺序语义——如果你要在 Gutenberg 的默认值之上做叠加,通常应使用默认优先级10;若需先于或晚于插件内置逻辑,可调整优先级参数(第三个参数)。
兼容性提示:WordPress 5.8 之前该钩子名为
block_editor_settings,现已废弃。如需兼容旧版本,可通过判断WP_Block_Editor_Context类是否存在(5.8 引入)来决定使用哪个过滤器名称。Gutenberg 仓库中的兼容层实践可参考 lib/compat 目录,其中针对不同 WordPress 版本拆分兼容代码。
以下示例在存在文章上下文时修改最大上传文件大小,可直接放入插件或主题的functions.php测试:
add_filter( 'block_editor_settings_all', 'example_filter_block_editor_settings_when_post_provided', 10, 2 ); function example_filter_block_editor_settings_when_post_provided( $editor_settings, $editor_context ) { if ( ! empty( $editor_context->post ) ) { $editor_settings['maxUploadFileSize'] = 12345; } return $editor_settings; }编辑器设置有数十个,无法在此逐一列举,以下各节针对常见定制场景给出完整示例。要查看全部设置当前值,打开编辑器后在浏览器控制台执行wp.data.select( 'core/block-editor' ).getSettings()即可实时获取。
按能力限制编辑器视图
限制代码编辑器访问
codeEditingEnabled默认值为true,控制用户能否在可视化编辑器之外访问代码编辑器。当设置为false时:设置菜单中的切换选项不可用,切换编辑器类型的键盘快捷键不生效,用户无法在可视化与代码编辑器之间切换。以下示例为无法激活插件的用户禁用代码编辑器:
add_filter( 'block_editor_settings_all', 'example_restrict_code_editor' ); function example_restrict_code_editor( $settings ) { $can_active_plugins = current_user_can( 'activate_plugins' ); // Disable the Code Editor for users that cannot activate plugins (Administrators). if ( ! $can_active_plugins ) { $settings[ 'codeEditingEnabled' ] = false; } return $settings; }限制可视化编辑器访问
与codeEditingEnabled类似,richEditingEnabled控制谁能使用可视化编辑器。该设置默认取user_can_richedit()的返回值,此函数同时检查用户是否具备可视化编辑权限以及浏览器是否支持相关能力。当将其设为false时,用户只能以代码编辑器方式编辑。
限制响应式编辑
responsiveEditingEnabled默认值为true,控制编辑器"视图"菜单中的 "Responsive styles"(响应式样式)选项是否可用。当设为false时:该选项不再渲染,Global Styles(全局样式)中的视口状态控件也被隐藏,用户无法针对单个视口(viewport)定向修改样式;但伪状态(如 hover)仍然可用,主题或 Global Styles 中已定义的响应式样式不受影响。
add_filter( 'block_editor_settings_all', 'example_disable_responsive_editing' ); function example_disable_responsive_editing( $settings ) { $settings['responsiveEditingEnabled'] = false; return $settings; }限制块状态编辑
blockStatesEditingEnabled默认值为true,控制块检查器(Block Inspector)与 Global Styles 中的块状态控件是否渲染。设为false后,用户无法从这些界面为状态(states)应用块样式;视口状态控件不受影响,仍由responsiveEditingEnabled控制。已保存在theme.json、Global Styles 或块style属性中的状态样式不受影响。
add_filter( 'block_editor_settings_all', 'example_disable_block_states_editing' ); function example_disable_block_states_editing( $settings ) { $settings['blockStatesEditingEnabled'] = false; return $settings; }设置默认图片大小与媒体相关开关
设置默认图片大小
编辑器中图片默认使用large尺寸。如果你配置了自定义图片尺寸,可通过imageDefaultSize修改默认值。以下示例将默认图片尺寸改为medium:
add_filter( 'block_editor_settings_all', 'example_set_default_image_size' ); function example_set_default_image_size( $settings ) { $settings['imageDefaultSize'] = 'medium'; return $settings; }禁用 Openverse
Openverse 媒体集成默认对所有 WordPress 站点启用,由enableOpenverseMediaCategory设置控制。禁用方法:
add_filter( 'block_editor_settings_all', 'example_disable_openverse' ); function example_disable_openverse( $settings ) { $settings['enableOpenverseMediaCategory'] = false; return $settings; }禁用字体库
字体库(Font Library)允许用户在站点上安装新字体,默认启用,由fontLibraryEnabled控制:
add_filter( 'block_editor_settings_all', 'example_disable_font_library' ); function example_disable_font_library( $settings ) { $settings['fontLibraryEnabled'] = false; return $settings; }禁用块检查器标签页
多数块在检查器中显示两个标签页:Settings(设置)与 Styles(样式)。可通过blockInspectorTabs设置禁用这些标签页。以下示例对所有块默认禁用标签页:
add_filter( 'block_editor_settings_all', 'example_disable_inspector_tabs_by_default' ); function example_disable_inspector_tabs_by_default( $settings ) { $settings['blockInspectorTabs'] = array( 'default' => false ); return $settings; }也可以针对特定块禁用。以下示例为自定义块my-plugin/my-custom-block关闭标签页,并注意使用_wp_array_get读取现有配置后通过array_merge合并,避免覆盖其他设置:
add_filter( 'block_editor_settings_all', 'example_disable_tabs_for_my_custom_block' ); function example_disable_tabs_for_my_custom_block( $settings ) { $current_tab_settings = _wp_array_get( $settings, array( 'blockInspectorTabs' ), array() ); $settings['blockInspectorTabs'] = array_merge( $current_tab_settings, array( 'my-plugin/my-custom-block' => false ) ); return $settings; }blockInspectorTabs是按块名索引的关联数组,default键控制全局默认行为,块名键(如core/paragraph)控制单块行为,后者优先级更高——这正是 Gutenberg 客户端检查器渲染时逐块读取该配置的依据。
禁用 Block Directory 与远程 Block Patterns
禁用 Block Directory
Block Directory 允许用户在编辑器中直接安装来自 WordPress.org 插件目录的块插件。禁用方式是移除负责入队其资源的动作:
remove_action( 'enqueue_block_editor_assets', 'wp_enqueue_editor_block_directory_assets' );这段代码应在插件或主题的初始化阶段(如init钩子)执行,确保在enqueue_block_editor_assets触发前完成移除。
禁用远程 Block Patterns
远程模式(如来自 WordPress.org 模式目录的 pattern)默认在编辑器中对用户可用。该功能由should_load_remote_block_patterns控制,默认值为true:
add_filter( 'should_load_remote_block_patterns', '__return_false' );Gutenberg 仓库的 packages/e2e-tests/mu-plugins/disable-remote-patterns.php 正是这样一个最小化测试插件——整个文件只有一句add_filter( 'should_load_remote_block_patterns', '__return_false' );,被 e2e 测试用于验证远程模式禁用场景,可作为生产环境的最小实现参考。禁用后编辑器将只展示本地注册的模式。
使用 JavaScript 过滤器扩展编辑器特性
JavaScript 侧通过@wordpress/hooks包提供的addFilter/addAction挂入编辑器内部流程。以下过滤器均需在 JavaScript 环境中注册(例如通过wp.hooks全局或在模块构建流程中导入@wordpress/hooks)。
editor.PostFeaturedImage.imageSize
该过滤器用于修改"文章特色图片"组件中显示的图片尺寸。默认值为'post-thumbnail';当指定尺寸在媒体对象中不存在时,会回退到full尺寸。它借鉴了经典编辑器中admin_post_thumbnail_size过滤器的设计。
import { addFilter } from '@wordpress/hooks'; const withImageSize = function ( size, mediaId, postId ) { return 'large'; }; addFilter( 'editor.PostFeaturedImage.imageSize', 'my-plugin/with-image-size', withImageSize );从源码看,该过滤器定义于 packages/editor/src/components/post-featured-image/index.jsx,在解析特色图片 URL 时通过applyFilters( 'editor.PostFeaturedImage.imageSize', ... )应用,回调可依据mediaId、postId按需返回不同尺寸。addFilter的第一个参数是钩子名,第二个参数是命名空间标识(建议使用插件名/功能名格式,避免与第三方冲突),第三个参数是回调函数,可选的第四个参数为优先级。
editor.PostPreview.interstitialMarkup
该过滤器用于自定义生成预览时显示的过渡(interstitial)消息:
import { addFilter } from '@wordpress/hooks'; const customPreviewMessage = function () { return '<b>Post preview is being generated!</b>'; }; addFilter( 'editor.PostPreview.interstitialMarkup', 'my-plugin/custom-preview-message', customPreviewMessage );其调用点位于 packages/editor/src/components/post-preview-button/index.jsx:markup = applyFilters( 'editor.PostPreview.interstitialMarkup', markup );。回调返回的字符串将作为预览生成期间的占位 HTML 注入预览窗口,可用于品牌化提示或展示加载状态。
media.crossOrigin
该过滤器用于设置或修改跨域媒体元素(<audio>、<img>、<link>、<script>、<video>)的crossOrigin属性。回调接收第二个参数mediaSrc(实际跨域媒体的 URL),便于依据来源决定返回值:
import { addFilter } from '@wordpress/hooks'; addFilter( 'media.crossOrigin', 'my-plugin/with-cors-media', // The callback accepts a second `mediaSrc` argument which references // the url to actual foreign media, useful if you want to decide // the value of crossOrigin based upon it. ( crossOrigin, mediaSrc ) => { if ( mediaSrc.startsWith( 'https://example.com' ) ) { return 'use-credentials'; } return crossOrigin; } );crossOrigin的合法值包括anonymous与use-credentials。一个典型应用是图片块的变换(transform)功能:为使跨域图片可被绘制进<canvas>(canvas 会污染无法读取),必须为其设置正确的 CORS 属性,本过滤器正是该场景的定制入口。
过滤编辑器 REST API 预加载路径
block_editor_rest_api_preload_paths用于过滤初始化编辑器时预加载的 REST API 路径数组,从而控制哪些公共数据随首屏一并下发。以下示例在存在文章上下文时追加OPTIONS请求以预取块类型信息:
add_filter( 'block_editor_rest_api_preload_paths', 'example_filter_block_editor_rest_api_preload_paths_when_post_provided', 10, 2 ); function example_filter_block_editor_rest_api_preload_paths_when_post_provided( $preload_paths, $editor_context ) { if ( ! empty( $editor_context->post ) ) { array_push( $preload_paths, array( '/wp/v2/blocks', 'OPTIONS' ) ); } return $preload_paths; }注意路径元素使用array( '/wp/v2/blocks', 'OPTIONS' )形式——这是 WordPress 预加载机制支持的"路径 + 请求方法"复合格式。Gutenberg 内部多处使用该过滤器注入依赖数据,例如 lib/compat/wordpress-7.1/preload.php 与 lib/experimental/dataform-inspector-preload.php 中的预加载逻辑。
客户端媒体处理(Client-side Media Processing)
客户端媒体处理在浏览器内使用 WebAssembly(vips 库)完成图片压缩、缩放、格式转换、旋转与缩略图生成。相关过滤器与参数如下,完整架构参见 客户端媒体架构说明,开发者指南参见 客户端媒体处理指南。
wp_client_side_media_processing_enabled总开关
该 PHP 过滤器控制客户端媒体处理是否启用,默认值为true:
// Disable client-side media processing entirely. add_filter( 'wp_client_side_media_processing_enabled', '__return_false' );也可以按条件禁用:
add_filter( 'wp_client_side_media_processing_enabled', 'example_disable_for_editors' ); function example_disable_for_editors( $enabled ) { if ( current_user_can( 'edit_posts' ) && ! current_user_can( 'manage_options' ) ) { return false; } return $enabled; }禁用后,所有上传回退到传统的服务端处理管线。该总开关同样统辖"动画 GIF 转视频"行为(见下文),因此是一个全局性主控。
客户端处理遵循的既有 WordPress 过滤器
客户端处理通过 REST API 从服务端读取以下既有过滤器配置,并在浏览器端图像处理时应用:
| 过滤器 | 作用 | 默认值/说明 |
|---|---|---|
big_image_size_threshold | 图像缩放阈值 | 默认 2560px,超过此尺寸的图像在客户端被缩放 |
image_editor_output_format | 输入 MIME 类型到输出 MIME 类型的映射,用于自动格式转换(如 JPEG → WebP) | 在客户端转码阶段应用 |
image_save_progressive | 控制渐进式(JPEG)/交错式(PNG、GIF)编码 | 在客户端压缩与格式转换阶段应用 |
wp_image_maybe_exif_rotate | 控制基于 EXIF 的旋转 | 客户端处理激活时,服务端旋转被禁用,由客户端处理 |
wp_editor_set_quality(JPEG 输出另含jpeg_quality) | 编码质量(1–100) | 服务端按每个注册尺寸解析该过滤器,并在上传响应的 size-awareimage_quality字段中报告结果,客户端在子尺寸缩放与转码时应用;没有独立的 JavaScript 质量过滤器 |
image_strip_meta | 控制是否剥离生成图像的元数据 | 在 REST 索引上导出;为false时客户端保留全部元数据(EXIF、XMP、IPTC),而不是剥离除色彩配置(及 HDR 增益图)之外的所有内容 |
image_max_bit_depth | 限制生成图像的位深(针对高比特深度 AVIF/HDR 源) | 在 REST 索引上导出,客户端编码器按 AVIF 编码器支持的位深(8、10 或 12 位)对齐 |
需要特别注意的是:客户端处理激活时,由于不涉及服务端WP_Image_Editor,以下三个服务端钩子永远不会触发:wp_image_editors、image_make_intermediate_size、image_memory_limit。依赖这些钩子的插件需要改用 客户端媒体处理指南中的服务端插件兼容章节 提供的替代信号。
关于可处理 MIME 类型:客户端处理没有针对 MIME 类型集合的过滤器。受支持的集合固定为CLIENT_SIDE_SUPPORTED_MIME_TYPES(image/jpeg、image/png、image/gif、image/webp、image/avif),定义于 packages/upload-media/src/store/constants.ts。此集合之外的格式回退到服务端处理;HEIC/HEIF 则走独立的基于 canvas 的解码路径。
REST API 附加参数
客户端处理在上传媒体时使用以下附加 REST API 参数:
generate_sub_sizes(布尔,默认true)—— 在POST /wp/v2/media上设为false时,服务端跳过缩略图生成。客户端处理会将其设为false,以便自行生成并 sideload 缩略图。convert_format(布尔,默认true)—— 在POST /wp/v2/media或POST /wp/v2/media/{id}/sideload上设为false时,服务端跳过基于image_editor_output_format过滤器的格式转换。当客户端已完成转换时使用。url(字符串)—— 传给POST /wp/v2/media而非文件主体时,服务端下载远程图片并 sideload。用于在跨域隔离(cross-origin-isolated)的编辑器中导入外部图片,规避浏览器跨域 fetch 失败的问题。
动画 GIF 转视频
不透明的动画 GIF 会在客户端转换为配套的 MP4/WebM 视频,图片块上会出现 "Display as video" 控件,允许用户将其切换为视频块的 "GIF" 变体。该行为没有专用过滤器——由上文的总开关wp_client_side_media_processing_enabled统一控制;当浏览器缺少 WebCodecs 视频编码能力时,回退为上传原始 GIF。详见 架构文档的动画 GIF 转视频章节 与 how-to 指南。
捕获并上报编辑器错误:editor.ErrorBoundary.errorLogged
界面某处的 JavaScript 错误不应导致整个应用崩溃。为此 React 使用"错误边界"(Error Boundary)机制——错误边界是能捕获其子组件树中任意位置 JavaScript 错误的 React 组件,并渲染备用 UI 而非崩溃的组件树。
Gutenberg 的editor.ErrorBoundary.errorLogged动作让你能接入错误边界,并获得错误对象以及 React 的 error info 对象(其componentStack属性描述错误在组件树中被抛出的位置)。典型用途是将错误发送到外部错误追踪工具:
import { addAction } from '@wordpress/hooks'; addAction( 'editor.ErrorBoundary.errorLogged', 'mu-plugin/error-capture-setup', ( error, errorInfo ) => { // Error is the exception's error object. // You can console.log it or send it to an external error-tracking tool. console.log ( error, errorInfo?.componentStack ); } );注意这里是addAction而非addFilter——该钩子是一个无返回值的副作用型动作,用于"监听"错误事件。其触发点位于 packages/editor/src/components/error-boundary/index.jsx,错误边界捕获异常后调用doAction( 'editor.ErrorBoundary.errorLogged', error, errorInfo )。你可以将error与errorInfo?.componentStack序列化后发送到 Sentry 等外部错误追踪服务,从而在不侵入编辑器内部实现的情况下获得全站编辑器错误的可观测性。
结语与进一步阅读
编辑器定制从上到下分为三个层次:PHP 侧的block_editor_settings_all设置开关、block_editor_rest_api_preload_paths数据预加载、should_load_remote_block_patterns等内容来源控制;JavaScript 侧的@wordpress/hooks过滤器与动作;以及客户端媒体处理所遵循的服务端既有过滤器。掌握这些钩子后,你可以精确裁剪编辑器功能、调整媒体行为,并把自定义逻辑无缝接入编辑器生命周期。
如需继续深入,推荐阅读本仓库中的相关文档:block-editor-settings.php(Gutenberg 如何注入默认设置)、客户端媒体架构说明、客户端媒体处理指南,以及参考指南总览 filters 下的其他过滤器文档。
【免费下载链接】gutenbergThe Block Editor project for WordPress and beyond. Plugin is available from the official repository.项目地址: https://gitcode.com/GitHub_Trending/gu/gutenberg
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考