Gutenberg 块编辑器自 WordPress 5.0 正式引入以来,已经彻底改变了内容编辑的方式。对于普通用户来说,它提供了更丰富的布局能力。对于开发者来说,Gutenberg 代表了一个全新的扩展维度:你可以创建自己的自定义块、修改核心块的行为、甚至构建完整的页面模板。掌握 Gutenberg 开发,意味着你可以给用户提供一个真正可视化、组件化的编辑体验。

创建自定义块需要一定的 JavaScript 基础,因为 Gutenberg 是基于 React 构建的。但 WordPress 官方提供了一个名为 @wordpress/create-block 的脚手架工具,可以大幅简化初始配置。在命令行中执行 npx @wordpress/create-block my-block,它会自动生成一个完整的插件目录,包含所有必要的配置文件、JavaScript 源码、PHP 入口文件。生成的代码中已经包含了一个简单的示例块,你只需要修改 JavaScript 文件中的 edit 和 save 函数,就可以定义块在编辑器中的样子和在前端输出的 HTML。

块的编辑界面和前端输出是分离的。edit 函数返回的是在后台编辑器中显示的 React 组件,而 save 函数返回的是最终保存到数据库并显示在前端的 HTML 字符串。这种设计允许你为编辑器和前端提供完全不同的渲染逻辑。例如,你可以让编辑器显示一个带滑块的颜色选择器,而前端只输出颜色值对应的 CSS 样式。

自定义块的开发中,attributes 是核心概念。它定义了块的数据结构,比如一个“按钮”块可能需要 texturlcolorsize 等属性。在 edit 函数中,你可以通过 setAttributes 来更新这些属性,每次更新都会触发界面重新渲染。InspectorControls 组件让你可以在右侧的设置侧边栏中添加控件,比如文本输入框、下拉选择器、颜色选择器等,这是用户配置块参数的入口。

修改核心块是另一种常见的需求。比如你想让“段落”块默认带上特定的 CSS 类,或者让“图片”块增加一个额外的图片尺寸选项,或者禁用“引用”块在某个项目中的使用。修改核心块主要通过 JavaScript 的过滤器实现,wp.hooks.addFilter 允许你拦截核心块的注册过程或渲染输出。举个例子,禁用某个核心块可以使用以下代码:

wp.hooks.addFilter('blocks.registerBlockType', 'my-plugin/disable-blocks', function(settings, name) {
    if (name === 'core/quote') {
        return null;
    }
    return settings;
});

这段代码会在块注册时拦截“引用”块,返回 null 让它不会被注册到编辑器中。

另一个常用的过滤器是 blocks.getSaveElement,它可以修改块的保存输出。你可以用它给所有核心块输出的内容包裹一个额外的 <div> 容器,或者给图片添加 loading="lazy" 属性,而不需要修改每个块的源码。

对于高级用户来说,Gutenberg 还支持创建块样式(Block Styles)和块变体(Block Variations)。块样式允许你在不改变块功能的前提下,为同一个块提供多种预置外观。比如“按钮”块可以提供“主要按钮”、“次要按钮”、“轮廓按钮”三种样式,用户可以在编辑器中一键切换。块变体则更进一步,允许你创建同一块类型的多个版本,每个版本有不同的默认属性和标题,比如“按钮”块变体可以是“购买按钮”和“分享按钮”,它们本质上是同一个块,但预设值不同。

如果你希望用户能直接选择完整的页面布局,而不是逐个搭建,可以创建块样板(Block Patterns)。块样板是一组预先配置好的块组合,用户插入后可以继续编辑。WordPress 核心自带了一部分块样板,你也可以在主题的 functions.php 中注册自己的样板:

register_block_pattern(
    'my-theme/hero-section',
    array(
        'title' => '英雄区',
        'description' => '包含背景图片、标题和按钮的头部区域',
        'content' => '<!-- 这里放块组合的 HTML 注释 -->',
        'categories' => array('banner'),
    )
);

对于性能有要求的项目,静态块(Static Block)和动态块(Dynamic Block)的选择也很重要。静态块的输出完全由 save 函数决定,内容直接存储在数据库中,不会在每次页面加载时重新计算。动态块则通过 PHP 的 render_callback 函数在服务端渲染,适合需要实时数据的内容,比如最新文章列表、用户个人信息等。

Gutenberg 开发的学习曲线比传统 PHP 主题开发要陡峭,因为它涉及现代 JavaScript 工具链(Webpack、ES6、React)。但一旦掌握了基础模式,它的扩展性和用户体验是传统编辑器无法相比的。对于需要给客户提供灵活内容编辑能力的项目,投入时间学习 Gutenberg 开发是非常值得的。