重写WordPress原生列区块:多InnerBlocks同步修改问题及ES5实现求助
重写WordPress原生columns区块相关问题
我计划重写WordPress(WP)原生columns区块的基础功能,原因如下:
- WP原生列区块自带了多款我不希望向用户开放的控件(变体选择、宽度滑块)
- 原生列区块允许用户插入任意类型的内容,我需要通过允许区块列表控制列内可插入的内容类型
我编写了如下edit函数:
( function( wp ) { var registerBlockType = wp.blocks.registerBlockType; var el = wp.element.createElement; var __ = wp.i18n.__; const { RadioControl, PanelBody, RangeControl } = wp.components; const { useBlockProps, InspectorControls, InnerBlocks } = wp.blockEditor; const allowedBlocks = [ 'core/paragraph', 'core/button' ]; registerBlockType( 'wpboiler-core/columns', { apiVersion: 2, title: __( 'Columns', 'columns' ), description: __( 'A block for displaying content in columns', 'columns' ), category: 'design', icon: 'schedule', supports: { html: false, }, attributes: { columnselect: { type: 'number', default: 2, }, }, edit: function(props) { const { attributes, setAttributes } = props; const { columnselect } = attributes; const onChangeColumnRange = value => setAttributes({ columnselect: value }); let columnsContainer = []; for(var n = 1; n <= columnselect; n++) { columnsContainer.push( el( 'div', null, el( InnerBlocks, { allowedBlocks: allowedBlocks, } ) ) ); }; return el( 'section', useBlockProps(attributes), // INSPECTOR CONTROL BEGIN el( InspectorControls, null, el( PanelBody, { title: "Columns", }, el( RangeControl, { min: 2, max: 4, value: columnselect, onChange: onChangeColumnRange, } ), ), ), // INSPECTOR CONTROL END el( 'div', { className: 'columns__container' }, columnsContainer ), ); }, save: function() { return null; }, } ); }( window.wp ) );
我遇到的问题是多个InnerBlocks的内容同步问题:函数生成了多个InnerBlocks区域,但编辑任意一个区域的内容,所有区域的内容都会同步变更。
我考虑的规避方案是自定义一个包含InnerBlock组件的column子区块,在for循环中渲染该子区块而非直接渲染InnerBlocks,思路大致如下:
for(var n = 1; n <= columnselect; n++) { columnsContainer.push( {RENDER_COLUMN_BLOCK} ); };
但我不确定该方案是否仍会出现内容同步变更的问题,是否需要给每个子区块实例分配唯一ID来区分不同实例?另外我当前在无构建步骤的ES5环境下开发,不清楚如何在父区块内渲染其他自定义组件,希望获得相关指导,恳请大家提供相关解决思路。
更新
我参考相关资料找到了一个临时解决方案:当InnerBlocks中子区块数量达到上限时隐藏区块添加按钮,分别注册自定义columns父区块和column子区块,每个column子区块单独配置允许插入的区块列表,代码如下:
// COLUMNS index.js ( function( wp ) { var registerBlockType = wp.blocks.registerBlockType; var el = wp.element.createElement; var __ = wp.i18n.__; const { useSelect } = wp.data; const { useBlockProps, InnerBlocks } = wp.blockEditor; const allowedBlocks = [ 'wpboiler-core/column' ]; registerBlockType( 'wpboiler/columns', { apiVersion: 2, title: __( 'Columns', 'columns' ), description: __( 'Displays content in columns', 'columns' ), category: 'design', icon: 'schedule', supports: { html: false, }, edit: function(props) { const { attributes, clientId } = props; const innerBlockCount = useSelect((select) => select('core/block-editor').getBlock(clientId).innerBlocks); return el( 'section', useBlockProps(attributes), __( 'Add columns by pressing the + icon. Maximum 4 columns', 'columns' ), el( 'div', { className: 'columns__container' }, innerBlockCount.length > 3 ? el( InnerBlocks, { allowedBlocks: allowedBlocks, renderAppender: false } ) : el( InnerBlocks, { allowedBlocks: allowedBlocks, } ), ) ); }, save: function() { return el( 'section', { className: 'columns' }, el( 'div', { className: 'columns__container' }, el( InnerBlocks.Content, {}, ), ), ); }, } ); }( window.wp ) );
// COLUMN - INDIVIDUAL index.js ( function( wp ) { var registerBlockType = wp.blocks.registerBlockType; var el = wp.element.createElement; var __ = wp.i18n.__; const { useBlockProps, InnerBlocks } = wp.blockEditor; const allowedBlocks = [ 'core/heading', 'core/paragraph', 'core/button', 'core/list' ]; registerBlockType( 'wpboiler/column', { apiVersion: 2, title: __( 'Column', 'column' ), description: __( 'Displays an individual column', 'column' ), category: 'widgets', icon: 'schedule', supports: { html: false, }, parent: [ 'wpboiler-core/columns' ], edit: function() { return el( 'div', useBlockProps(), el( 'div', { className: 'column' }, el( InnerBlocks, { allowedBlocks: allowedBlocks, }, ), ), ); }, save: function() { return el( 'div', { className: 'column' }, el( InnerBlocks.Content, {}, ), ); }, } ); }( window.wp ) );
该方案虽然能实现类似原生列区块的效果,但不再支持通过范围控件选择列数,和预期功能不完全一致,欢迎大家提供其他优化建议。
内容的提问来源于stack exchange,提问作者Bagseye
相关产品推荐
相关产品推荐

