重新创建列块-构建自定义块



作为标题,我希望重新创建WP列块的基本功能。原因是-

  • WP添加了一些我不希望用户拥有的控件(变量,宽度滑块)
  • 允许的块,一列,让用户添加任何类型的内容,他们喜欢。我希望有一个允许的块列表控制这一点

我创建了以下编辑函数:


( 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。这个函数创建了一个InnerBlock区域列表。但是,编辑一个区域会改变所有区域。

我相信解决这个问题的一种方法是创建一个包含InnerBlock组件的自定义column块,并在for循环中渲染它而不是InnerBlock。所以类似于…


for(var n = 1; n <= columnselect; n++) {
columnsContainer.push(
{RENDER_COLUMN_BLOCK}
);
};

但是如果我这样做了,我还会遇到同样的问题吗?编辑一个专栏实际上就会编辑所有的专栏?是否每个实例都需要有一个ID来知道哪个实例正在被编辑?

我也在努力找出我如何在一个块内渲染另一个自定义组件时,不使用构建步骤(es5)。

对这项任务的任何帮助都将不胜感激。

更新遇到以下帖子后,我创建了一个"解决方案",如下所示,一旦达到所需的列数,它基本上会关闭块追加器。每个新实例创建一个自定义块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
) );

但是,这样做就不需要range控件/columns select了。但它确实以与本机列块相似(尽管不完全相同)的方式起作用。

同样,欢迎其他建议。

您是正确的,因为您不能在单个块内拥有多个<InnerBlocks>。正如您建议的那样,您的最佳选择是使用两个块:一个columns包装器块与一个只能包含column块的<InnerBlocks>组件。每个column块可以有自己的<InnerBlocks>组件。

您不需要遍历任何内容,因为<InnerBlocks>组件将负责为您呈现所有column块。本质上,你将有一个columns块输出:

<InnerBlocks 
allowedBlocks={ ['my/columns'] }
orientation="horizontal"
/>

那么你的column块将只输出:

<InnerBlocks/>

这就是WordPress核心栏块的工作原理。我自己也成功地用它来替换内置的列块。

最后,虽然添加一个构建步骤似乎要做很多额外的工作,但我强烈建议这样做。它使代码更容易阅读和使用。

最新更新