Gutenberg List 块源码深度解析:core/list 块的结构、属性、支持项与渲染原理
Gutenberg List 块源码深度解析core/list 块的结构、属性、支持项与渲染原理【免费下载链接】gutenbergThe Block Editor project for WordPress and beyond. Plugin is available from the official repository.项目地址: https://gitcode.com/GitHub_Trending/gu/gutenberg导读本文以 Gutenberg 仓库中 List 块官方文档 为核心骨架结合packages/block-library/src/list/目录下的block.json、edit.jsx、save.jsx、index.php、utils.js、transforms.js等源码实现全面剖析core/list列表块从块元数据定义、属性Attributes与支持项Supports、混合块Hybrid Block的静态保存与服务端增强到有序列表的起始值/编号样式/倒序配置再到与段落、标题块的相互转换与旧版迁移机制。读完本文你将掌握core/list块的完整数据模型与渲染链路能够以此为范本理解 Gutenberg 核心块的注册与实现方式。一、块概览core/list是什么core/list是 Gutenberg 内置的“列表”块用于展示按特定顺序组织的一组条目。官方文档给出的核心标识如下名称Namecore/list分类Categorytext文本类API 版本API Version3block.json中的apiVersion: 3块类型Block TypeHybrid混合块——静态保存static save 服务端增强关键词Keywordsbullet list、ordered list、numbered list用于在插入器中被搜索命中在 block.json 中这些信息被声明为块元数据{ $schema: https://schemas.wp.org/trunk/block.json, apiVersion: 3, name: core/list, title: List, category: text, description: An organized collection of items displayed in a specific order., keywords: [ bullet list, ordered list, numbered list ], textdomain: default }块关系Block Relationshipscore/list通过allowedBlocks仅允许一种内部块——core/list-item。也就是说列表块的内容完全由core/list-item子块构成列表的嵌套多级缩进实际是list-item内再嵌套list块实现。二、属性Attributes深度解析属性通过block.json中的attributes属性定义官方文档给出了完整清单属性类型默认值说明orderedbooleanfalse是否为有序列表Role: contentvaluesstring来源Sourcehtml选择器Selectorol,ulRole: contenttypestring—编号样式类型startnumber—起始编号值reversedboolean—是否倒序placeholderstring—占位符对应block.json中的完整定义attributes: { ordered: { type: boolean, default: false, role: content }, values: { type: string, source: html, selector: ol,ul, multiline: li, default: , role: content }, type: { type: string }, start: { type: number }, reversed: { type: boolean }, placeholder: { type: string } }几个关键细节values的读取来源source: html搭配selector: ol,ul即从保存的 HTML 中直接取ol或ul元素的内部 HTML 作为内容。这是旧版v1列表块的存储方式。ordered决定标签在 save.jsx 中const TagName ordered ? ol : ul;false渲染ultrue渲染ol。placeholder仅存在于编辑态编辑器内未输入内容时展示的占位提示不进入最终保存的 HTML。role: content标记这些属性属于“内容”角色便于编辑器按内容语义处理例如在复制/粘贴、模板锁定等场景下的行为。关于values的版本演进从源码 edit.jsx 可以看出values属性实际上是历史遗留Gutenberg 6.0 起列表块已迁移为“内嵌块inner blocks”结构即core/list包裹多个core/list-item但为了兼容使用旧格式模板如自定义文章类型模板创建的块useMigrateOnLoad钩子在块加载时检测到values非空便调用migrateToListV2将其一次性迁移为新的 inner blocks 结构并输出一条deprecated警告deprecated( Value attribute on the list block, { since: 6.0, version: 6.5, alternative: inner blocks, } );迁移逻辑位于 utils.js先根据ordered构造ol/ulDOM 元素回填values字符串并带上start、reversed、type属性再交给rawHandler解析为标准的 block 树。这也是为什么官方文档中把该块归类为 Hybrid 块的背景之一。三、支持项Supports编辑器能力矩阵支持项同样定义在 block.json 中决定了侧边栏与工具栏能为该块提供哪些样式与行为能力anchortrue—— 允许为列表块设置 HTML 锚点id属性便于页内跳转。align[wide, full]—— 支持“宽”与“全宽”两种对齐方式没有居中/左/右因为块级元素默认撑满内容宽度。htmlfalse—— 关闭“编辑为 HTML”能力避免用户破坏列表的内部结构。typographyfontSizetrue字号lineHeighttrue行高实验性支持__experimentalFontFamily、__experimentalFontWeight、__experimentalFontStyle、__experimentalTextTransform、__experimentalTextDecoration、__experimentalLetterSpacing默认控件fontSize: truecolorgradientstrue渐变色linktrue链接颜色默认控件背景与文字色spacingmargin与padding均为true。interactivity.clientNavigationtrue—— 支持客户端导航区块交互框架用于前端无刷新页面切换场景。listViewtrue—— 允许在“列表视图List View”侧栏中展示并操作该块。额外的非文档化支持项__unstablePasteTextInline粘贴纯文本时内联处理、__experimentalOnMerge支持与相邻块合并、__experimentalSlashInserter支持在块内输入/触发插入器、__experimentalBorder实验性边框支持含 color/radius/style/width。官方文档只汇总了文档化的支持项实际上block.json中还包含上面这些补充声明——这正是“以文档为骨架、以源码为佐证”的典型差异点。CSS 选择器Selectorsselectors: { border: .wp-block-list:not(.wp-block-list .wp-block-list) }边框样式只会应用到最外层的列表块上:not(.wp-block-list .wp-block-list)排除了嵌套在其它列表内部的列表避免嵌套列表中边框样式叠加。四、混合块静态保存 服务端增强的渲染链路官方文档的 Block Markup 节给出了该块的注释标记示例!-- wp:list {ordered:false,values:} -- !-- Content... -- !-- /wp:list --4.1 编辑与保存逻辑在 save.jsx 中保存逻辑非常简洁根据ordered渲染ol或ul透传reversed与start并以内联样式的方式写入编号类型const { ordered, type, reversed, start } attributes; const TagName ordered ? ol : ul; return ( TagName { ...useBlockProps.save( { reversed, start, style: { listStyleType: ordered type ! decimal ? type : undefined, }, } ) } InnerBlocks.Content / /TagName );注意两点实现细节listStyleType只在ordered true且type ! decimal时才写入——decimal阿拉伯数字是ol的浏览器默认样式无需显式声明。列表内容完全交给InnerBlocks.Content /输出也就是所有core/list-item子块。编辑态edit.jsx与保存态保持同样的TagName由 tag-name.jsx 提供并叠加工具栏控件“无序列表 / 有序列表”切换按钮ordered: false/trueRTL 环境自动切换图标方向formatListBulletsRTL等缩出Outdent按钮当当前块的父块是core/list-item时可用点击后把父级list-item拆开、将子块提升为同级见useOutdentList通过useInnerBlocksProps设置defaultBlock: core/list-item与directInsert: true实现回车直接新建列表项、无需手动选择块的流畅输入体验。4.2 服务端渲染增强wp-block-list类混合块的含义是“保存静态标记但服务端可在渲染时增强”。index.php 中的block_core_list_render回调通过WP_HTML_Tag_Processor找到内容中的第一个ol/ul标签并追加wp-block-list类function block_core_list_render( $attributes, $content ) { if ( ! $content ) { return $content; } $processor new WP_HTML_Tag_Processor( $content ); $list_tags array( OL, UL ); while ( $processor-next_tag() ) { if ( in_array( $processor-get_tag(), $list_tags, true ) ) { $processor-add_class( wp-block-list ); break; } } return $processor-get_updated_html(); }该增强从 WordPress 6.6.0 起生效since 6.6.0用途是保证历史遗留的、保存时还没有wp-block-list类的旧列表块在前端也能获得正确的类名例如ol被转换为ol classwp-block-list以便应用样式。块通过register_block_type_from_metadata注册并挂载render_callbackfunction register_block_core_list() { register_block_type_from_metadata( __DIR__ . /list, array( render_callback block_core_list_render ) ); } add_action( init, register_block_core_list );4.3 块级样式style.scss 为前端提供基础样式ol, ul { box-sizing: border-box; }并为带背景色的列表补足内边距:root :where(.wp-block-list.has-background) { padding: $block-bg-padding; }五、有序列表高级设置编号样式、起始值与倒序当ordered: true时侧边栏会渲染OrderedListSettingsordered-list-settings.jsx这是一个基于ToolsPanel的设置面板包含三项配置5.1 编号样式List style下拉选项LIST_STYLE_OPTIONS对应 CSSlist-style-type值界面文案值CSS 效果Numbers数字decimal1, 2, 3…Uppercase letters大写字母upper-alphaA, B, C…Lowercase letters小写字母lower-alphaa, b, c…Uppercase Roman numerals大写罗马数字upper-romanI, II, III…Lowercase Roman numerals小写罗马数字lower-romani, ii, iii…在 utils.js 中还保留了一张历史映射表LIST_STYLES将 HTML 传统type属性值A、a、I、i归一化为现代 CSS 值upper-alpha等用于从粘贴的 HTML 转换与旧块迁移。5.2 起始值Start valueTextControltypenumberstep1允许输入任意整数作为起始编号。源码对输入做了解析与兜底onChange{ ( value ) { const int parseInt( value, 10 ); setAttributes( { // 允许清空例如空字符串以取消起始值 start: isNaN( int ) ? undefined : int, } ); } }即输入非数字时属性被置为undefined不写入 HTML输入整数时对应ol startN属性。5.3 倒序Reverse orderToggleControl控制reversed属性开启后输出ol reversed浏览器会从大到小显示编号如 3、2、1配合start可定义最大编号。这三个属性在save.jsx中都被直接透传到ol标签上是标准的 HTML 原生能力映射因此前端无需任何 JavaScript 即可正确渲染。六、变换Transforms与段落、标题的互相转换及粘贴识别transforms.js 定义了core/list的全部变换规则6.1 从段落/标题转换block 变换多块选择isMultiBlock: true选择多个段落/标题块时每个块的内容直接变成一个core/list-item仅单块时用wordpress/rich-text的split( value, \n )按换行拆分成多个列表项转换时会保留原块的anchor属性。6.2 从 HTML 粘贴转换raw 变换selector: ol,ul表示粘贴内容中的ol/ul会被识别为列表块。getListContentSchema递归构造了允许的嵌套结构ul li ul允许、ul ul不允许并允许ol携带type、start、reversed属性最终交给createListBlockFromDOMElementutils.js把 DOM 树逐层转换为core/listcore/list-item的块树嵌套列表被解析为list-item的子块。6.3 前缀输入prefix 变换输入*或-加空格生成无序列表项输入1.或1)加空格生成ordered: true的有序列表项。6.4 反向转换to列表可以转换回core/paragraph或core/headinggetListContentFlat将整棵列表树含嵌套项拍平为内容字符串数组每个字符串生成一个段落/标题块嵌套层级在转换中被展开。七、示例与默认模板index.js 中TEMPLATE [ [ core/list-item ] ]新建列表块时默认预置一个空列表项example示例展示了五个经典列表项Alice、The White Rabbit、The Cheshire Cat、The Mad Hatter、The Queen of Hearts该示例会显示在块插入器的预览区最后通过initBlock完成块注册export const init () initBlock( { name, metadata, settings } );。块的旧版本逻辑位于 deprecated.jsx负责兼容早期保存的 HTML 结构更早的 v1 结构使用values属性的内联 HTML 列表则依赖上文所述的migrateToListV2在加载时升级。八、总结从core/list看 Gutenberg 核心块的设计范式通过core/list块可以提炼出 Gutenberg 核心块的通用架构模式元数据驱动block.json一份文件同时声明名称、分类、属性、支持项、选择器与前后端样式句柄前后端均据此注册内容用 inner blocks 表达列表项作为子块存在块本身只负责容器标签与语义属性ol/ul、start、reversed向后兼容靠迁移旧版values属性通过加载期迁移钩子自动升级同时配合deprecated声明保留旧结构解析混合渲染增强静态保存保证内容可移植服务端render_callback对历史内容做渐进增强如补全wp-block-list类丰富的编辑器能力矩阵通过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),仅供参考