I am trying to dynamically add the template in my InnerBlock for that I have tried the following code:
const edit = props => {
var {
className,
attributes,
setAttributes,
clientId
} = props;
var { templateList } = attributes;
const ALLOWBLOCKS = ['ss-gutenberg-block/accordion-child'];
setAttributes({ blockId: clientId });
return (
<Fragment>
<div className={className}>
<div className = { "accordionParentWrapper" }>
<InnerBlocks
template = { templateList }
allowedBlocks = { ALLOWBLOCKS }
templateLock = { "true" }
/>
<span
className = { "dashicons dashicons-plus editor-icons" }
onClick = {() => setAttributes({ templateList: [...templateList, ['ss-gutenberg-block/accordion-child'] ] })}
></span>
<span
className = { "dashicons dashicons-minus editor-icons" }
onClick = {() => setAttributes({ templateList: templateList.length ? templateList.splice(-1, 1) : templateList })}
></span>
</div>
</div>
</Fragment>
);
}
and the templateList attribute consists of [['ss-gutenberg-block/accordion-child']]
by default. I want to add or remove my child block dynamically from Innerblock. The buttons are working fine and Adding and Removing into array. But visually the blocks are not added or removed.
I am trying to dynamically add the template in my InnerBlock for that I have tried the following code:
const edit = props => {
var {
className,
attributes,
setAttributes,
clientId
} = props;
var { templateList } = attributes;
const ALLOWBLOCKS = ['ss-gutenberg-block/accordion-child'];
setAttributes({ blockId: clientId });
return (
<Fragment>
<div className={className}>
<div className = { "accordionParentWrapper" }>
<InnerBlocks
template = { templateList }
allowedBlocks = { ALLOWBLOCKS }
templateLock = { "true" }
/>
<span
className = { "dashicons dashicons-plus editor-icons" }
onClick = {() => setAttributes({ templateList: [...templateList, ['ss-gutenberg-block/accordion-child'] ] })}
></span>
<span
className = { "dashicons dashicons-minus editor-icons" }
onClick = {() => setAttributes({ templateList: templateList.length ? templateList.splice(-1, 1) : templateList })}
></span>
</div>
</div>
</Fragment>
);
}
and the templateList attribute consists of [['ss-gutenberg-block/accordion-child']]
by default. I want to add or remove my child block dynamically from Innerblock. The buttons are working fine and Adding and Removing into array. But visually the blocks are not added or removed.
That's not how templates work.
A template is the initial block layout, a starting point.
Changing the template won't do anything because the original template was used to create blocks and those blocks have already been created. Think about it, if it worked the way you thought it did, adding or removing from the template would erase all the content, and your content would be erased when the post loads.
What you've done is attempted to create a custom block appender, so instead of reinventing that feature you should instead use the block appender props and APIs. Templates are not appropriate for what you're trying to do.
TLDR: If you want a custom block appender/inserter, use a custom block inserter/appender, don't try to make templates dynamic, they aren't and can't be made dynamic, that's not how templates work.
To dynamically add or remove templates in the InnerBlocks
component, you need to manage the template list state properly and ensure that changes to the template list trigger a re-render of the InnerBlocks component.
const { InnerBlocks } = wp.editor;
const { Fragment } = wp.element;
const edit = props => {
const { className, attributes, setAttributes } = props;
const { templateList } = attributes;
const ALLOWBLOCKS = ['ss-gutenberg-block/accordion-child'];
const addTemplate = () => {
const newTemplateList = [...templateList, ['ss-gutenberg-block/accordion-child']];
setAttributes({ templateList: newTemplateList });
};
const removeTemplate = () => {
const newTemplateList = [...templateList];
newTemplateList.pop(); // Remove the last template
setAttributes({ templateList: newTemplateList });
};
return (
<div className={className}>
<div className="accordionParentWrapper">
<InnerBlocks
template={templateList}
allowedBlocks={ALLOWBLOCKS}
templateLock="all"
/>
<span
className="dashicons dashicons-plus editor-icons"
onClick={addTemplate}
></span>
<span
className="dashicons dashicons-minus editor-icons"
onClick={removeTemplate}
></span>
</div>
</div>
);
};
export default edit;
created separate functions addTemplate
and removeTemplate
to handle adding and removing templates from the template list after that inside function built a new array newTemplateList
based on the current templateList and either added or removing a template from it then we calling setAttributes
to update the templateList attribute with the new array.
<Fragment>
is not needed as it only has a single child – Tom J Nowell ♦ Commented Jan 19, 2021 at 9:46