Gutenberg: Clarify Documentation for How to Unregister a Single Block with JS

Created on 10 Nov 2018  路  12Comments  路  Source: WordPress/gutenberg

Describe the bug
Having reviewed the handbook, blog posts, and other various tickets such as #4848, I can't find any documented way to remove a single block.

The wp.blocks.unregisterBlockTypes() method in the handbook doesn't seem to work and allowed_block_types only works for whitelisting blocks.

Given that I don't want to have to keep my whitelist up to date with new blocks from core or plugins, being able to blacklist blocks seems extremely reasonable.

Expected behavior
Based on what I currently can find, I would expect this to work:

add_filter( 'allowed_block_types', 'mrw_unset_bad_blocks' );
function mrw_unset_bad_blocks( $blocks ) {
    unset($blocks['core/verse']);
    return $blocks;
}

Desktop (please complete the following information):
Win 10, Firefox 63, WP 5.0-beta3

[Feature] Extensibility [Type] Documentation [Type] Task

Most helpful comment

Unregistering the block when the window loads is not an ideal solution. In theory additional blocks may be able to be added to after the window has loaded.

There is another issues I ran into when disabling blocks. When I disabled the core/quote block it would generate a major error if I tried to use the core/list block. Assumedly because the list block provides a transformation to a quote. If any core blocks are modified in the future to handle additional transformations this may introduce this issue if you happen to unregister a transformable block type.

In my case I opted to to just remove unsupported blocks from the inserter.

const visibleBlocks = [
    'core/paragraph',
    'core/header',
    'core/list',
]

wp.hooks.addFilter('blocks.registerBlockType', 'hideBlocks', (pSettings, pName) => {
    if (visibleBlocks.indexOf(pName) === -1) {
        return Object.assign({}, pSettings, {
            supports: Object.assign({}, pSettings.supports, {inserter: false})
        })
    }

    return pSettings
})

All 12 comments

The allowed_block_types filter doesn't provide an array of all the block slugs by default, instead it's only a boolean true which means all blocks. See also #10951.

wp.blocks.unregisterBlockType( 'core/verse' ); is working as expected though. How are you adding your script? Does it work if you enter the line into your browser console?

@ocean90 It does work in the console. That makes me think that the documentation is incomplete. I'm guessing that simply putting wp.blocks.unregisterBlockType( 'core/verse' ); into a JS file will fire the code too early?

My code was that exact line copy-pasted into a JS file and then enqueued from a plugin. I confirmed that the file was loaded. Looking just now, I had missed that this appears in the console:

Block "core/verse" is not registered.

It sounds like the "bug" is incomplete documentation then? Having poked through #10951 and a bunch of other linked tickets, I still don't see anything about how to do this. A pointer would be useful.

And FWIW, my "expected behavior" for allowed_block_types stands. I now see that it's probably a "feature not a bug", but I don't understand why and it sure would be convenient if the code I posted worked. Given that WordPress is also so extensible, a blacklist is much more useful than a whitelist.

@mrwweb I got this to work by enqueuing a script with array( 'wp-blocks', 'wp-element' ) as dependencies. In that script then you run your wp.blocks.unregisterBlockType( 'core/verse' ); it should work just fine.

I'm actually running into a separate issue where I unregister too many and break things!

@brianpiccione thanks for the reply. A couple things:

  1. It looks like wp-element isn't needed, as best I can tell. I got it working eventually with this:
add_action( 'enqueue_block_editor_assets', 'mrw_gutenberg_js' );
function mrw_gutenberg_js() {
    wp_enqueue_script(
        'simple-gutenberg-js',
        plugins_url( 'js/gutenberg.js', __FILE__ ),
        array( 'wp-blocks' )
    );
}
  1. My problem was that I needed to make wp.blocks.unregisterBlockType() run with window.onload. I had tried it naked as the documentation literally says and also with document.addEventListener('DOMContentLoaded'. Here's my functional JS code:
window.onload = function(){
    wp.blocks.unregisterBlockType( 'core/verse' );
};

What's the proper way to use wp.blocks.unregisterBlockType() and can we update the documentation so it's clearer?

Unregistering the block when the window loads is not an ideal solution. In theory additional blocks may be able to be added to after the window has loaded.

There is another issues I ran into when disabling blocks. When I disabled the core/quote block it would generate a major error if I tried to use the core/list block. Assumedly because the list block provides a transformation to a quote. If any core blocks are modified in the future to handle additional transformations this may introduce this issue if you happen to unregister a transformable block type.

In my case I opted to to just remove unsupported blocks from the inserter.

const visibleBlocks = [
    'core/paragraph',
    'core/header',
    'core/list',
]

wp.hooks.addFilter('blocks.registerBlockType', 'hideBlocks', (pSettings, pName) => {
    if (visibleBlocks.indexOf(pName) === -1) {
        return Object.assign({}, pSettings, {
            supports: Object.assign({}, pSettings.supports, {inserter: false})
        })
    }

    return pSettings
})

Unregistering the block when the window loads is not an ideal solution. In theory additional blocks may be able to be added to after the window has loaded.

Totally makes sense. I just don't know what the right place is to do it! Whatever it is should be included with the documentation.

When I disabled the core/quote block it would generate a major error if I tried to use the core/list block

That's quite troubling... It sounds like it may simply be unsafe to ever unregister blocks if that's always going to be the case!

In my case I opted to to just remove unsupported blocks from the inserter.

Seems like a good workaround at least for now. Does that remove it from the "/" inserter options as well?

Does that remove it from the "/" inserter options as well?

Sorry not sure what you mean. It removes it from the editor GUI... But it wouldn't stop the blocks being added programatically or affect any blocks that are already inserted (they can still be edited or deleted).

@mcshaman: There are two default ways to add a block the "+" buttons and by typing "/" in an empty paragraph block. I'm curious if it hides it from the latter feature as well as the "+".

Cool... Didn't know that! Yep it is hidden there as well.

Also FYI it also removes them from the _Transform to_ menu.

Tested and confirmed using WordPress 5.0.1 and Gutenberg 4.7.0 master @ ddac4f3cf that if I follow the instructions at https://wordpress.org/gutenberg/handbook/designers-developers/developers/filters/block-filters/#using-a-blacklist which are to:

Add a my-plugin directory to /wp-content/plugins/ and then add my-plugin.php with the following content:

function my_plugin_blacklist_blocks() {
    wp_enqueue_script(
        'my-plugin-blacklist-blocks',
        plugins_url( 'my-plugin.js', __FILE__ ),
        array( 'wp-blocks' )
    );
}
add_action( 'enqueue_block_editor_assets', 'my_plugin_blacklist_blocks' );

Add a my-plugin.js file with the following content:

wp.blocks.unregisterBlockType( 'core/verse' );

And then activate the plugin, create a new post, and try to add the verse block鈥攖he result is that I see the following error in the console and the verse block still works.

screen shot 2018-12-17 at 2 30 48 pm

(Forgive me if my description is a bit oversimplified! I did worry I took the handbook instructions too literally and would be happy to correct it if you spot anything I've done wrong in my testing. 馃檪)

Related: #6443, #5661, #6448.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

aaronjorbin picture aaronjorbin  路  3Comments

maddisondesigns picture maddisondesigns  路  3Comments

spocke picture spocke  路  3Comments

mhenrylucero picture mhenrylucero  路  3Comments

jasmussen picture jasmussen  路  3Comments