自定义Gutenberg区块freeform内容随机丢失问题咨询
问题根因定位
你的freeform内容随机丢失核心是代码里3个致命逻辑错误导致的,和内容本身无关:
blocks.getSaveContent.extraProps过滤器用法完全错误
这个钩子的设计用途是给区块最外层DOM节点添加HTML属性(比如id、自定义data属性、ARIA标签),绝对不能用来修改props.children区块内容。你直接在这个钩子里篡改freeform块的输出内容,会直接破坏Gutenberg的块校验机制:Gutenberg每次打开编辑器加载文章时,会把数据库里存储的序列化块内容,和当前站点代码运行生成的save输出做逐字符比对,一旦匹配不上就会判定块损坏,触发块恢复流程,freeform(经典编辑器块)本身校验逻辑更特殊,校验失败时最坏情况会直接清空内容。- 正则替换逻辑过于粗暴,直接破坏块边界标记
你写的这堆正则没有做任何边界匹配,很容易误替换正常内容,尤其是最后两条:
这两条直接把所有Gutenberg块的起始/结束注释标记替换成普通注释,直接毁掉了块结构的边界标识,Gutenberg解析器扫到被改坏的标记时,会直接跳过对应块的内容解析,判定为空块。props.children = props.children.replace(/<!-- wp:/g,"<!--"); props.children = props.children.replace(/<!-- \/wp:/g,"<!--"); - edit组件存在语法残片
你的edit方法JSX里有一行拼接错误的残片:
这段无效代码在部分WordPress版本、构建环境下不会直接抛错,但会导致InnerBlocks的状态同步逻辑异常,加上你给InnerBlocks开了</div>Content', 'biscuit' ) }</label></h4>templateLock="all",子块(包括freeform)的属性更新很容易出现不同步,保存时写入空内容。
另外你的段落转自定义块逻辑也有隐患:wp.blocks.rawHandler是用来处理完整原始HTML序列化内容的,你直接把core/paragraph块处理过的attributes.content传进去,很容易生成结构残缺的freeform脏数据,后续编辑时校验失败就会丢内容。
修复方案
按优先级依次处理:
- 立刻删除当前写的
setExtraPropsToBlockType过滤器,不要在编辑器保存阶段修改块的序列化内容。你想去掉块注释标记、清理冗余标签的需求,放到PHP层用render_block过滤器实现,只改前端访客看到的输出,不要改数据库里存的编辑器原始内容,从根源上避免块校验失败。 - 删掉edit组件里的JSX残片,保证组件结构闭合正确。
- 修正块转换逻辑:从core/paragraph转换到自定义块时,不要用rawHandler生成freeform块,直接创建
core/paragraph块塞到InnerBlocks里即可,减少不必要的freeform块生成。 - 加内容兜底:给自定义块新增一个隐藏的
contentBackup属性,监听编辑器保存事件,保存前把内部freeform块的内容同步备份到这个属性里;同时加blocks.getBlockAttributes过滤器处理core/freeform块,一旦解析出来的内容为空,就从父块的备份属性里恢复内容,避免直接丢数据。 - 生产环境排查冲突:因为测试环境无法复现,需要在和生产一致的staging环境逐个禁用插件/主题排查,重点检查带内容自动格式化、XSS过滤、经典编辑器增强功能的插件,这类插件经常会误删Gutenberg的块注释标记,和你的自定义逻辑叠加后就会触发内容丢失。
内容的提问来源于stack exchange,提问作者Luphuza
相关产品推荐
相关产品推荐

