WordPress 6自定义动态块嵌套InnerBlocks更新后内容不保存
问题说明
WordPress 6环境下开发支持嵌套内部块的自定义动态块时,Gutenberg编辑界面内块操作正常,但更新页面刷新后,块内嵌套内容无法保存。
复现步骤
可通过两种方式复现问题:
- 方式1:获取对应插件压缩包,解压后放入
wordpress/wp-content/plugins目录激活即可测试 - 方式2:手动搭建测试插件,在WordPress插件目录新建名为
block_dynamic_newtype的文件夹,在目录内创建以下4个文件:
block.json
{ "apiVersion": 2, "title": "Block - dynamic - newtype", "name": "blockexample/block-dynamic-newtype", "category": "custom-fno-category", "icon": "star-filled", "editorScript": "file:./block.js" }
block.asset.php
<?php return array('dependencies' => array('wp-blocks', 'wp-element', 'wp-i18n' ), 'version' => 'a35cc1c098b69994c9c6d6dc1416bb90');
index.php
<?php /** * Plugin Name: Block - dynamic - newtype */ function block_dynamic_newtype_register_render_callback( $attr, $content ) { return '<div style="border: 1px solid black;">This is content of dynamic block: '.$attr['content'].' place for other blocks:<br> <div>'.$content.'</div> </div>'; } function block_dynamic_newtype_register() { $asset_file = include( plugin_dir_path( __FILE__ ) . 'block.asset.php'); wp_register_script( 'block-dynamic-newtype', plugins_url( 'block.js', __FILE__ ), $asset_file['dependencies'], $asset_file['version'] ); register_block_type( 'blockexample/block-dynamic-newtype', array( 'api_version' => 2, 'editor_script' => 'block-dynamic-newtype', 'render_callback' => 'block_dynamic_newtype_register_render_callback' )); } add_action( 'init', 'block_dynamic_newtype_register' ); ?>
block.js
console.log('block dynamic newtype loaded'); ( function ( blocks, blockEditor, data, element ) { var el = element.createElement; var RichText = blockEditor.RichText; var InnerBlocks = blockEditor.InnerBlocks; var useBlockProps = blockEditor.useBlockProps; blocks.registerBlockType( 'blockexample/block-dynamic-newtype', { apiVersion: 2, title: 'Block - dynamic - newtype', icon: 'star-filled', category: 'custom-fno-category', attributes: { content: { type: 'string' }, }, edit: function (props) { var blockProps = useBlockProps(); var content = props.attributes.content; function onChangeContent( newContent ) { props.setAttributes( { content: newContent } ); } return el( "div", blockProps, el("div", {class: 'fno_block_editor'}, el("h3", null, "Blok - dynamický - newtype"), el("div", {class: 'block_space'}, el( InnerBlocks ) ), ) ); }, save: function( props ) { return (InnerBlocks.Content); }, } ); } )( window.wp.blocks, window.wp.blockEditor, window.wp.data, window.wp.element );
问题根因
代码两处不符合WordPress动态块开发规范,直接导致嵌套内容无法存储:
- PHP端注册块类型时,未声明对
innerBlocks的支持,WordPress保存文章时不会解析、存储该块下的嵌套子块数据 - JS端
save方法返回值错误。动态块的所有前端渲染逻辑由PHP回调处理,不需要在JS端定义保存输出,save方法必须返回null。当前返回InnerBlocks.Content是静态块的写法,会触发Gutenberg块标记校验错误,保存时系统会直接丢弃校验不通过的块内容。
修复方案
- 修改
index.php中的块注册逻辑,新增innerBlocks支持声明,修改后代码如下:
register_block_type( 'blockexample/block-dynamic-newtype', array( 'api_version' => 2, 'editor_script' => 'block-dynamic-newtype', 'render_callback' => 'block_dynamic_newtype_register_render_callback', 'supports' => [ 'innerBlocks' => true ] ));
更规范的写法是直接传入插件目录路径,让系统自动读取block.json内的配置,避免重复定义参数:
// 替换原有register_block_type调用即可,无需手动注册脚本、声明api版本等参数 register_block_type( __DIR__, array( 'render_callback' => 'block_dynamic_newtype_register_render_callback' ));
- 修改
block.js中的save方法,直接返回null:
save: function( props ) { return null; },
修改完成后重新激活插件,插入动态块添加嵌套内容后更新,刷新后内容即可正常保存、渲染。
内容的提问来源于stack exchange,提问作者maeros
相关产品推荐
相关产品推荐

