plugins - How to dynamically add template in Innerblock?

admin2025-01-07  3

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.

Share Improve this question asked Jan 19, 2021 at 9:05 Night CrawlerNight Crawler 1 3
  • the <Fragment> is not needed as it only has a single child – Tom J Nowell Commented Jan 19, 2021 at 9:46
  • Okay will do that! Thank you! But that is not what I am looking for! – Night Crawler Commented Jan 19, 2021 at 11:26
  • That's why I left it as a comment not an answer/solution – Tom J Nowell Commented Jan 19, 2021 at 11:31
Add a comment  | 

2 Answers 2

Reset to default 0

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.

转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1736253856a157.html

最新回复(0)