Gutenberg 分组块(core/group)完全指南:布局容器、块变体与源码级实现解析
【免费下载链接】gutenbergThe Block Editor project for WordPress and beyond. Plugin is available from the official repository.项目地址: https://gitcode.com/GitHub_Trending/gu/gutenberg
导读
core/group(Group,分组)是 WordPress 块编辑器 Gutenberg 中最常用的布局容器块之一,其核心职责是"把块收集进一个布局容器"(Gather blocks in a layout container)。本文以 packages/block-library/src/group/README.md 的官方 API 参考为骨架,结合同目录下的block.json、edit.jsx、save.jsx、variations.js、transforms.js、deprecated.jsx等源码,完整讲解该块的属性、能力(supports)、变体、转换、编辑与保存机制,以及服务端渲染和主题样式,帮助开发者从"会用"进阶到"懂原理"。
一、块元数据总览
分组块在 packages/block-library/src/group/block.json 中定义,属于静态块(Static Block)——即渲染后的 HTML 标记会直接保存进文章内容(post content),而非在服务端动态渲染。
| 项目 | 值 |
|---|---|
| 名称(Name) | core/group |
| 分类(Category) | design(设计) |
| API 版本(API Version) | 3 |
| 块类型(Block Type) | 静态块(保存于文章内容中) |
| 关键词(Keywords) | container、wrapper、row、section |
| 文本域(Textdomain) | default |
关键词container、wrapper、row、section意味着用户在插入器(inserter)中搜索这四个词时也能检索到该块。块的图标与注册入口在 packages/block-library/src/group/index.js 中,通过initBlock()完成注册,同时导出了edit、save、deprecated、variations、transforms等完整设置。
二、属性(Attributes)详解
属性通过 block.json 中的attributes属性定义,分组块只有两个属性:
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
tagName | string | "div" | 分组容器的 HTML 标签名 |
templateLock | string \| boolean | — | 枚举值:all、insert、contentOnly、false |
2.1 tagName:容器标签
tagName控制分组容器最终使用的 HTML 标签。默认是div,但在编辑器的高级(Advanced)检查器面板中,可以通过HTMLElementControl控件切换标签。从 edit.jsx 的源码可以看到,可选项包括:
Default (<div>)→div<header><main><section><article><aside><footer>
这一能力使分组块可以直接充当页面的语义化结构元素,而无须另写自定义块。保存端 save.jsx 会取出tagName作为实际渲染标签:
export default function save( { attributes: { tagName: Tag } } ) { return <Tag { ...useInnerBlocksProps.save( useBlockProps.save() ) } />; }2.2 templateLock:锁定内部模板
templateLock用于锁定分组块内部的块结构,适用于模板或模式(pattern)场景,可选值及含义:
| 值 | 行为 |
|---|---|
all | 完全锁定,用户无法移动、删除或新增内部块 |
insert | 允许移动和删除,但不允许新增块 |
contentOnly | 只允许编辑内部块的内容,禁止任何结构性修改 |
false | 不锁定(默认行为) |
在编辑器中,templateLock被透传给useInnerBlocksProps的配置对象(见 edit.jsx),从而约束内部块容器的行为。
三、能力(Supports)全景:分组块能做什么
supports声明了分组块继承自全局样式系统(Global Styles)的全部能力。逐项解读如下:
align:支持"wide"(宽)与"full"(全宽)两种对齐,工具栏会显示对齐控制。anchor:支持设置 HTML 锚点(id),便于页内链接与目录跳转。ariaLabel:支持无障碍标签。html:false——不允许直接编辑 HTML,保证块结构完整。background:支持背景图片(backgroundImage)、背景尺寸(backgroundSize)与渐变(gradient),且默认控件中背景图片与渐变默认开启。color:支持渐变(gradients)、标题颜色(heading)、按钮颜色(button)、链接颜色(link);默认控件中背景色与文字色默认开启。shadow:支持阴影。spacing:外边距仅支持top/bottom,内边距(padding)完全支持,块间距(blockGap)支持水平与垂直方向;默认控件中padding与blockGap默认开启。dimensions:支持最小高度(minHeight)与最小宽度(minWidth)。position:支持粘性定位(sticky)。typography:支持字号(fontSize)与行高(lineHeight),block.json 中同时还开启了字体族、字重、字风格、文本转换、文本装饰、字间距等实验性能力(__experimental*系列),默认控件中字号默认开启。layout:支持子块尺寸调整(allowSizingOnChildren),这是分组块能作为灵活布局容器的关键。interactivity:支持客户端导航(clientNavigation)。allowedBlocks:允许通过属性限制内部可容纳的块类型。__experimentalOnEnter/__experimentalSettings:编辑体验相关的实验性开关。__experimentalBorder:block.json 中还声明了完整的边框能力(颜色、圆角、样式、宽度),默认控件全部开启。
注意:README 的自动生成文档只列出了正式(非实验)能力,而
block.json中还包含__experimentalBorder、__experimentalFontFamily等实验性支持项,这些在 block.json 中可逐一核对。以仓库实际配置为准。
四、块标记(Block Markup):保存进内容的 HTML
作为静态块,分组块把标记直接写入文章内容。README 给出的标准输出如下:
<!-- wp:group {"align":"full","backgroundColor":"secondary","layout":{"type":"default"}} --> <div class="wp-block-group alignfull has-secondary-background-color has-background"> <!-- wp:paragraph --> <p>This is a group block.</p> <!-- /wp:paragraph --> <!-- wp:paragraph --> <p>Group block content.</p> <!-- /wp:paragraph --> </div> <!-- /wp:group -->解析这个标记可以发现几个关键点:
- 注释标记(block comment)携带 JSON 序列化的属性:
align、backgroundColor、layout。服务端解析器依据这些属性还原块配置。 - 容器类名由
blockProps自动生成:wp-block-group是基础类,alignfull来自对齐设置,has-secondary-background-color与has-background来自颜色能力。 - 内部子块(这里是两个段落)作为嵌套块序列化保存在容器内,由
InnerBlocks机制管理。
4.1 从编辑到保存的渲染一致性
编辑端 edit.jsx 中,当主题支持布局(themeSupportsLayout)或布局类型为flex/grid时,useInnerBlocksProps直接作用于块根节点;否则为了向后兼容,会额外保留一层.wp-block-group__inner-container包裹容器。保存端与之对应,现代版本只输出单层标签,而旧版本的双层 div 结构则通过 deprecated.jsx 中的"双 div 版本"(第 120-157 行)在加载旧内容时完成兼容解析。
五、布局变体(Variations):Group / Row / Stack / Grid
分组块内置了四种变体,定义于 variations.js,分别对应不同的layout类型,是分组块灵活性的核心:
| 变体名称 | 标题 | 描述 | layout 属性 |
|---|---|---|---|
group | Group | 把块收集进一个容器 | { type: 'constrained' }(约束宽度,默认变体) |
group-row | Row | 水平排列块 | { type: 'flex', flexWrap: 'nowrap' } |
group-stack | Stack | 垂直排列块 | { type: 'flex', orientation: 'vertical' } |
group-grid | Grid | 网格排列块 | { type: 'grid' } |
group变体通过isDefault: true标记为默认变体,即插入"Group"块时的默认行为。group-row与group-grid通过isActive: ['layout.type']判断当前是否激活,group-stack则额外检查layout.orientation。- 四种变体的
scope均为['block', 'inserter', 'transform'],意味着它们既可在插入器中被选择,也可作为块转换的目标。
5.1 占位选择器:第一次插入时的引导体验
当分组块为空、且未设置任何颜色/字号/自定义样式、布局类型既非flex也非grid时,编辑端会显示一个占位选择器,引导用户从四种变体中选择布局。其判定逻辑封装在 placeholder.jsx 的useShouldShowPlaceHolder钩子中:
const [ showPlaceholder, setShowPlaceholder ] = useState( ! hasInnerBlocks && ! backgroundColor && ! fontSize && ! textColor && ! style && usedLayoutType !== 'flex' && usedLayoutType !== 'grid' );占位界面由GroupPlaceHolder组件渲染(见 placeholder.jsx),为每种变体提供 48×48 的 SVG 示意图按钮,点击后调用selectVariation(见 edit.jsx)将变体属性写入块并选中该块。
六、块转换(Transforms):把任意块组合成 Group
transforms.js 定义了从其他块转换为分组块的能力:选中多个任意类型块(isMultiBlock: true,blocks: ['*'])后,可通过块工具栏的"Group"操作将其包裹进一个分组块。其核心逻辑值得注意:
- 遍历所有待组合块,取出
align属性,取其中"最宽"的对齐设置(wide/full)应用到新分组块上(widestAlignment逻辑); - 使用
cloneSanitizedBlock克隆每个子块——注释明确说明:如果直接复用原块引用,switchToBlockType会替换原块导致它们同时从原位和新组内消失,克隆是避免该问题的关键; - 通过
createBlock('core/group', { align, layout: { type: 'constrained' } }, groupInnerBlocks)生成新分组块,并继承所有子块。
七、向后兼容:deprecated 版本的演进史
deprecated.jsx 保存了 5 个历史版本,清晰展示了分组块的演进路径:
- 默认布局版本:处理旧的
layout.inherit与layout.contentSize配置,迁移为type: 'constrained'; - 双 div 版本:旧标记为外层标签包裹
.wp-block-group__inner-container内层 div; - 无全局样式支持版本:使用
backgroundColor/textColor等独立属性(非style对象),通过migrateAttributes迁移为现代style.color结构; - 文字颜色类 bug 版本:曾因未把文字颜色类写入
clsx导致类名缺失,需特殊迁移; - v1 版本:最初没有内层容器 div,直接渲染
InnerBlocks.Content。
每一版都实现了migrate迁移函数与对应的save输出,保证历史文章内容在加载时被正确解析、升级并重新保存。这也解释了为什么分组块作为"历史包袱最重"的核心块之一,仍能保持向前兼容。
八、主题样式与前端呈现
分组块关联两个样式文件,均在 block.json 的editorStyle(wp-block-group-editor)与style(wp-block-group)中声明:
- style.scss:为
.wp-block-group设置box-sizing: border-box(因为该块支持自定义内边距),并给布局为 constrained 的分组块设置position: relative,以保证负外边距场景下块的重叠表现符合预期。 - theme.scss:针对带背景的分组块(
.wp-block-group.has-background)增加低特异性的默认内边距,与段落块(paragraph)的默认内边距保持一致($block-bg-padding),使带背景的分组与段落视觉对齐。
九、示例配置:官方 example 与主题支持
packages/block-library/src/group/index.js 为分组块定义了example示例,展示了一个典型的"居中约束 + 对称内边距"的展示卡片结构:约束布局(type: 'constrained')、justifyContent: 'center'、四周4em/3em内边距,内部嵌套标题、段落、间距与按钮块。该示例用于插入器与块库的预览缩略图,可直接作为主题开发者设计分组样式时的参考样例。
十、自定义开发者速查
- 在主题中调整样式:可直接针对
.wp-block-group、.wp-block-group.has-background、.wp-block-group.is-layout-constrained、.wp-block-group.is-layout-flex、.wp-block-group.is-layout-grid等类编写主题 CSS。 - 在模式/模板中使用:可通过
templateLock锁定结构,通过allowedBlocks限制内容,结合tagName输出语义化标签。 - 作为第三方块的容器:利用
allowSizingOnChildren布局支持,可让内部子块共享容器的尺寸调整能力。 - 服务端说明:分组块本身是纯前端静态渲染块,
packages/block-library/src/group/目录下没有index.php;它的 PHP 侧职责由块库其余基础设施承担。若需在 PHP 中过滤其输出,可挂接render_block钩子并按块名core/group判断。
结语
core/group看似只是一个"装块的容器",实则集成了布局系统(constrained/flex/grid)、全局样式(颜色、间距、排版、阴影、背景)、变体选择、批量转换与多层向后兼容机制,是理解 Gutenberg 块架构的绝佳范本。想要深入了解实现细节,可继续研读 packages/block-library/src/group/ 目录下的全部源码,以及 block.json 中各项supports对应的底层实现。
【免费下载链接】gutenbergThe Block Editor project for WordPress and beyond. Plugin is available from the official repository.项目地址: https://gitcode.com/GitHub_Trending/gu/gutenberg
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考