When we register a block type we define how the block structure should be in the moment it is added to the editor. After the block type is added to the editor we have an actual block.
The initial template prop in the InnerBlock defines which innerBlocks should be added when adding the (root) block type. Once added the prop has no effect as the block has already been created. From there on we need to modify that specific block props.
So in your case we need to dispatch an action to modify the block data in the store. We could achieve this with wp.data.dispatch
, wp.data.withDispatch
or wp.data.useDispatch
. My suggestion is to use wp.data.useDispatch
which makes use of React hooks.
We modify the block innerBlocks using the replaceInnerBlocks function. This function takes the block clientId
and an array of blocks.
The thing here is that we are modifying blocks that might have content. I suggest taking a look at how we can deal with it in this other answer. What we do is take the existent blocks and merge them if necessary with programatically created blocks (using wp.blocks.createBlock
).
const { times } = lodash;
const { __ } = wp.i18n;
const { createBlock } = wp.blocks;
const { PanelBody, SelectControl } = wp.components;
const { InnerBlocks, InspectorControls } = wp.blockEditor;
const { useDispatch, useSelect } = wp.data;
const TEMPLATE = [
[
"myblocks/myblock",
{
a: "b",
c: "d"
}
]
];
export const settings = {
title: __("My Block", "mytextdomain"),
description: __("Description", "mytextdomain"),
keywords: [__("block")],
supports: {
align: false,
alignWide: false
},
attributes: {
a: {
type: "string"
},
c: {
type: "string"
}
},
edit: props => {
const { className, clientId } = props;
const { replaceInnerBlocks } = useDispatch("core/block-editor");
const { inner_blocks } = useSelect(select => ({
inner_blocks: select("core/block-editor").getBlocks(clientId)
}));
return (
<div className="myblock">
<InspectorControls>
<PanelBody title={__("Select", "mytextdomain")} initialOpen={true}>
<SelectControl
onChange={selected => {
let inner_blocks_new = inner_blocks;
/*
// If we need to add 3 new blocks
inner_blocks_new = [
...inner_blocks,
...times(3, () =>
createBlock("myblocks/myblock")
)
];
*/
/*
// If we need to remove blocks after the third one
inner_blocks_new = inner_blocks.slice(0, 3);
*/
replaceInnerBlocks(clientId, inner_blocks_new, false);
}}
label={__("Select Item", "mytextdomain")}
options={options}
/>
</PanelBody>
</InspectorControls>
<h1>{__("Some Title")}</h1>
<InnerBlocks
template={TEMPLATE}
allowedBlocks={["myblocks/myblock"]}
templateLock={false}
/>
</div>
);
},
save: () => null
};