Gutenberg: Allowing adding/deleting/replacing of InnerBlocks / ChildBlocks

Created on 29 May 2019  Â·  4Comments  Â·  Source: WordPress/gutenberg

Hello! I have created a custom Gutenberg (Call to Action) block. This block has a RadioControl to switch between two types. When switching the option, the InnerBlocks of the custom block should change. I have found no other way to do it, than to look at the whole content, search for my block and do replacements:

let newContent = wp.data.select('core/editor').getEditedPostAttribute('content');
let editedContent = newContent.replace( /* ...search my block, do some replacements... */ );
let blocks = wp.blocks.parse( editedContent );          
wp.data.dispatch( 'core/editor' ).resetBlocks( blocks );

⇧ This isn't really performant.

Is there a way to replace only the InnerBlocks of a block? I don't want to parse the whole editor content. Setting the childBlocks to an empty array empty won't update the editor, the InnerBlocks don't disappear. After saving and refreshing the page, they will:

const currentBlock = select( 'core/editor' ).getBlocksByClientId( clientId )[ 0 ];
let childBlocks = currentBlock.innerBlocks;
childBlocks = [ ];

⇧ This doesn't update the editor.

Is there a way of manipulating only the InnerBlocks of one block in Gutenberg?

[Type] Question

Most helpful comment

There are a bunch of select and dispatch functions you can use to manipulate blocks: https://github.com/WordPress/gutenberg/blob/7e0dce0da7177b94ffa58266c11f3b0ca8763ff7/docs/designers-developers/developers/data/data-core-editor.md

To remove all child blocks, you should be able to use this code:

const currentBlock = select( 'core/editor' ).getBlocksByClientId( clientId )[ 0 ];
const childBlocks = currentBlock.innerBlocks;

const clientIds = childBlocks.map( block => block.clientId );
wp.data.dispatch( 'core/editor' ).removeBlocks( clientIds );

You can also add new blocks with insertBlocks():

const newBlock = wp.blocks.createBlock( 'core/paragraph', {} );
wp.data.dispatch( 'core/editor' ).insertBlocks( newBlock, 0, clientId );

For your use case, I would take a look at the replaceBlocks() function. I have never used it so can't give you an example, but I guess it works very similiar.

All 4 comments

There are a bunch of select and dispatch functions you can use to manipulate blocks: https://github.com/WordPress/gutenberg/blob/7e0dce0da7177b94ffa58266c11f3b0ca8763ff7/docs/designers-developers/developers/data/data-core-editor.md

To remove all child blocks, you should be able to use this code:

const currentBlock = select( 'core/editor' ).getBlocksByClientId( clientId )[ 0 ];
const childBlocks = currentBlock.innerBlocks;

const clientIds = childBlocks.map( block => block.clientId );
wp.data.dispatch( 'core/editor' ).removeBlocks( clientIds );

You can also add new blocks with insertBlocks():

const newBlock = wp.blocks.createBlock( 'core/paragraph', {} );
wp.data.dispatch( 'core/editor' ).insertBlocks( newBlock, 0, clientId );

For your use case, I would take a look at the replaceBlocks() function. I have never used it so can't give you an example, but I guess it works very similiar.

Thanks for answering @Netzberufler. I'll close the issue for now, as that answer seems very comprehensive.

The only thing I'd add is that I'd consider using 'core/block-editor' if possible, since that largely supercedes 'core/editor'. While the latter will continue to be supported, my understanding is there will be deprecation notices in the not too distant future.

@talldan @Netzberufler Thanks for your answer.

One more detail question, when adding new inner blocks (not only one):

const newBlock = wp.blocks.createBlock( 'core/paragraph', {} );

⇧ Can this be defined as an array? I tried that, it throws an error.

wp.data.dispatch( 'core/editor' ).insertBlocks( newBlock, 0, clientId );

⇧ Because the name insertBlocks is plural, it suggests that you can add multiple or nested blocks at once. Is that true?

I can't find information about that here: https://github.com/WordPress/gutenberg/blob/7e0dce0da7177b94ffa58266c11f3b0ca8763ff7/docs/designers-developers/developers/data/data-core-editor.md

createBlock does only create a single block at a time. As far as I know there's no plural version:
https://github.com/WordPress/gutenberg/tree/master/packages/blocks#createBlock

insertBlocks can handle multiple blocks provided for its first argument in an array. There's also insertBlock for a single block, which actually calls straight through to insertBlocks:
https://github.com/WordPress/gutenberg/blob/f7cf606c133434a2b105a6cf457b83208f5ab6fc/packages/block-editor/src/store/actions.js#L353-L418

Was this page helpful?
0 / 5 - 0 ratings

Related issues

moorscode picture moorscode  Â·  3Comments

nylen picture nylen  Â·  3Comments

wpalchemist picture wpalchemist  Â·  3Comments

jasmussen picture jasmussen  Â·  3Comments

ellatrix picture ellatrix  Â·  3Comments