Gutenberg: Prevent specific block from removing

Created on 30 Jun 2019  路  8Comments  路  Source: WordPress/gutenberg

I'm inserting a block programmatically and I want to prevent users from removing it. Is there any way to disable the "Remove Block" option for a specific block?

[Feature] Block API [Type] Enhancement

Most helpful comment

Great! This would be a highly welcomed addition.

All 8 comments

Hey @woorise! There's no API that lets third parties disable the _Remove Block_ option for a specific block.

There is, however, Templates which lets you specify which blocks should be in a post by default and lock them down so that the user can't add/remove any further blocks.

Does that cover your use case? If not, could you go into some detail on what you're trying to accomplish?

I tried the Templates and more specifically the PHP locking snippet with the "insert" option to lock a specific block but it doesn't allow me to insert any other block (different type).

Is this the default behavior?

Yes that's right, template locking prevents both insertion and deletion.

I don't think it makes sense to allow one without the other. For example, if a user can insert blocks but not delete them, how can they remove blocks that are accidentally inserted?

Could you go into some detail on what you're trying to accomplish?

Template locking prevents insertion and deletion for a specific block or for all blocks?

These are my requirements:

  • A specific block will be added programmatically
  • Users will be able to move this block but not remove it
  • Users will be able to insert other blocks (I mean other types of blocks not the one that we have locked)

Thanks for the extra info, @woorise!

Right now a developer can prevent the user from inserting and deleting _all_ blocks using template locking, but it is not possible to disable inserting and deleting _a specific_ block.

Potentially we could do this by adding supports.remove to the block configuration. This would mirror supports.inserter.

Great! This would be a highly welcomed addition.

If you want to make sure that you can't remove a specific block (myplugin/important-block), you could do something like this:

const getBlockList = () => wp.data.select( 'core/block-editor' ).getBlocks();
let blockList = getBlockList();
wp.data.subscribe( () => {
  const newBlockList = getBlockList();
  if (
    newBlockList.length < blockList.length
    && blockList.some( block => block.name === 'myplugin/important-block' ) )
    && newBlockList.every( block => block.name !== 'myplugin/important-block' )
  ) {
    wp.data.dispatch( 'core/block-editor' ).resetBlocks( blockList );
  }
  blockList = newBlockList;
} );

This code will make sure that at least one block with the name myplugin/important-block will be present in the editor.

Also check: https://bdwm.be/gutenberg-prevent-specific-block-from-being-removable/

@pwkip Thanks for the workaround. But still, it would be nice to have some officially supported block setting for that.

Btw I think that in your fix might be an issue with nested blocks. Some block (e.g. core/columns OR core/column) may carry other blocks on innerBlocks property. blockList.some and blockList.every check only the top level so you may miss the myplugin/important-block if it is inside a column or some other block that support nested blocks.

You can use this function for searching for a block.

const findBlock = (blocks, name) => (
  blocks.reduce((result, block) => {
    if (result) {
      return result;
    }
    if (block.name === name) {
      return block;
    }
    if (Array.isArray(block.innerBlocks) && block.innerBlocks.length) {
      return findBlock(block.innerBlocks, name);
    }
    return null;
  }, null)
);
Was this page helpful?
0 / 5 - 0 ratings

Related issues

hedgefield picture hedgefield  路  3Comments

jasmussen picture jasmussen  路  3Comments

nylen picture nylen  路  3Comments

ellatrix picture ellatrix  路  3Comments

moorscode picture moorscode  路  3Comments