Whitelisting & Blacklisting Blocks

The Gutenberg editor (slated for WordPress core release in v5.0) ships with more than 60 blocks, many of which are likely irrelevant for many projects.

The official Gutenberg documentation provides methods for whitelisting and blacklisting blocks, but at the time of writing this, those documented methods don’t work, and there are several open issues in the Gutenberg Github repo regarding this.

If you need to whitelist (or blacklist) blocks today, below is an outline of how I accomplished this.

Note, that at the time of writing this, I’m using Gutenberg v2.8, and based on how quickly Gutenberg is moving, I don’t have much confidence that this will work for future versions, so take my tips/tricks with a grain of Gutenberg salt.

tl;dr

The approach below documents how to whitelist blocks in Gutenberg. You can use this to blacklist if that’s your cup of tea as well. The gist of what needs to happen:

  • Defined a list of allowed blocks
  • Pass that list from the server to the client on page load
  • Use that list with some custom JS to remove blocks that are not whitelisted

Define the list of allowed blocks & pass to the client

Gutenberg core ships with an allowed_block_types filter, but there are several issues open related to this filter not being well respected by the Gutenberg client (#6363, #6070, #5893), so before you get burned trying to use this, we’re going to define our own list of blocks and send the list up to the client.

Here we define a filterable array, and localize that array to be passed up to the client with the custom Gutenblock JS you’re already enqueuing to interact with Gutenberg (assuming you already have custom JS being enqueued)

$localized_data = apply_filters( 'my_localized_gutenblock_data_filter', [] ) ;
wp_localize_script( 'my-custom-gutenblocks-js', 'gutenblockHelpers', $localized_data );

Next, we’re going to add a whitelist of blocks to this filtered data.

add_filter( 'my_localized_gutenblock_data_filter', function( $localized_data ) {

  $localized_data['whitelistedBlocks'] = [
    'core/image',
    'core/paragraph'
  ];

  return $localized_data;

}, 10, 1 );

This adds a new whitelistedBlocks key to our localized data, with an array of blocks that we want to whitelist, in this case, core/image and core/paragraph.

Now, if we did this properly, we should see our `gutenblockHelpers` object enqueued and accessible via window.gutenblockHelpers. You can see this in your browser console.

 

Use the whitelist on the client to filter Gutenberg

Now that we’re successfully passing up a list of whitelistedBlocks up to the client, we need some JS to use that list and tell Gutenberg to respect it.

We need to enqueue a new script like so:

wp_enqueue_script(
  'gutenberg-block-whitelist',
  "/path/to/your/gutenbergWhitelist.min.js",
  [ 'wp-i18n', 'wp-element', 'wp-blocks', 'wp-components', 'wp-api' ],
  1,
  true
);

Note the dependencies. I noticed that if this script is loaded without the proper dependencies, it will be enqueued too early and not work. I can’t explain all the reasons why these need to be the dependencies, but these are the dependencies I declared to get things working and without them, things went a bit wonky.

Next, we need to write the script that we’re enqueueing.

Note:, I’m using es6 which is being transpiled/minified by Webpack & Babel. I’m using the 10up theme scaffold which has Webpack configured and a build script that handles this. 

let whitelistedBlocks =gutenblockHelpers &&gutenblockHelpers.whitelistedBlocks ?gutenblockHelpers.whitelistedBlocks : null;
const {unregisterBlockType, getBlockTypes} = wp.blocks;


/**
 * We have to wait until all blocks have been registered before unregistering them.
 *
 * This is SUPER fragile and hacky and will likely cause things to break over time, so I suggest
 * keeping an eye on Gutenberg to see how blacklisting/whitelisting evolves in the core plugin.
 */
wp.api.init().then( ( () => {

	/**
	 * Loop through the blacklisted blocks and unregister them.
	 *
	 * The blacklist is added to the gutenblockHelpers global via wp_localize_script.
	 */
	if (
		whitelistedBlocks.length &&
		typeof unregisterBlockType !== 'undefined' &&
		getBlockTypes !== 'undefined'
	) {
		getBlockTypes().forEach( block => {
			if ( whitelistedBlocks.indexOf( block.name ) === -1 ) {
				unregisterBlockType( block.name );
			}
		} );
	}

} ) );

This script checks to see if there’s a list of whitelisted blocks passed up to the client from our localized data.

If there is, it waits for the wp.api to initialize, then if the core Gutenberg methods getBlockTypes and unregisterBlockType is available and the whitelist has items defined, it asks Gutenberg for a list of ALL registered blocks usinggetBlockTypes, then it loops through them and unregisters all that are NOT part of the list of whitelisted blocks.

At this point, if you try and interact with Gutenberg, the only blocks you should now have access to are the core/paragraph and core/image blocks.

Customizing the whitelist for Post Types or other conditions

It’s likely that you may want to customize the list of blocks that are allowed for certain post_types.

To do that, you just need to adjust your filtered list of blocks, like so:

add_filter( 'my_localized_gutenblock_data_filter', function( $localized_data ) {

  global $post;

  $localized_data['whitelistedBlocks'] = [
    'core/image',
    'core/paragraph'
  ];

  // whitelist a custom block for a custom post type
  if ( 'my-custom-type' === $post->post_type ) {
    array_push( $localized_data, 'your-prefix/custom-block' );
  }

  // Remove the core/image block for a specific post type
  if ( isset(  $localized_data['whitelistedBlocks'][''core/image'] ) && 'my-custom-type' === $post->post_type ) {
    unset( $localized_data['whitelistedBlocks'][''core/image'] );
  }

  return $localized_data;

}, 10, 1 );

 

Posted by Jason Bahl

Principal Software Engineer at WP Engine in Denver, CO. I love problem solving and working with WordPress. I'm the creator and maintainer of WPGraphQL. I'm passionate about Open Source software and the web. When I'm not writing code, you'll find me spending time with my beautiful wife Rachel and my 2 sons Andrew and Blake. I also enjoy playing and watching soccer.

57 Replies to “Whitelisting & Blacklisting Blocks”

  1. […] Bahl, a WordPress Engineer at Digital First Media, published a tutorial that explains how to whitelist and blacklist blocks using a filterable, localized […]

    Reply

  2. […] Bahl, a WordPress Engineer at Digital First Media, published a tutorial that explains how to whitelist and blacklist blocks using a filterable, localized […]

    Reply

  3. […] Bahl, a WordPress Engineer at Digital First Media, published a tutorial that explains how to whitelist and blacklist blocks using a filterable, localized […]

    Reply

  4. […] Bahl, a WordPress Engineer at Digital First Media, published a tutorial that explains how to whitelist and blacklist blocks using a filterable, localized […]

    Reply

  5. […] Bahl, a WordPress Engineer at Digital First Media, published a tutorial that explains how to whitelist and blacklist blocks using a filterable, localized […]

    Reply

  6. […] Bahl, a WordPress Engineer at Digital First Media, published a tutorial that explains how to whitelist and blacklist blocks using a filterable, localized […]

    Reply

  7. […] Whitelisting & Blacklisting Blocks – Jason shows you how. […]

    Reply

  8. […] Bahl, a WordPress Engineer at Digital First Media, published a tutorial that explains how to whitelist and blacklist blocks using a filterable, localized […]

    Reply

  9. […] itself: because blocks are registered in the frontend, unregistering an already-registered block is done by loading an additional script. In my opinion, this is one of the biggest challenges for the Gutenberg contributors: to put in […]

    Reply

  10. […] itself: because blocks are registered in the frontend, unregistering an already-registered block is done by loading an additional script. In my opinion, this is one of the biggest challenges for the Gutenberg contributors: to put in […]

    Reply

  11. […] itself: because blocks are registered in the frontend, unregistering an already-registered block is done by loading an additional script. In my opinion, this is one of the biggest challenges for the Gutenberg contributors: to put in […]

    Reply

  12. […] itself: because blocks are registered in the frontend, unregistering an already-registered block is done by loading an additional script. In my opinion, this is one of the biggest challenges for the Gutenberg contributors: to put in […]

    Reply

  13. […] itself: because blocks are registered in the frontend, unregistering an already-registered block is done by loading an additional script. In my opinion, this is one of the biggest challenges for the Gutenberg contributors: to put in […]

    Reply

  14. […] itself: because blocks are registered in the frontend, unregistering an already-registered block is done by loading an additional script. In my opinion, this is one of the biggest challenges for the Gutenberg contributors: to put in […]

    Reply

  15. […] itself: because blocks are registered in the frontend, unregistering an already-registered block is done by loading an additional script. In my opinion, this is one of the biggest challenges for the Gutenberg contributors: to put in […]

    Reply

  16. […] itself: because blocks are registered in the frontend, unregistering an already-registered block is done by loading an additional script. In my opinion, this is one of the biggest challenges for the Gutenberg contributors: to put in […]

    Reply

  17. […] itself: because blocks are registered in the frontend, unregistering an already-registered block is done by loading an additional script. In my opinion, this is one of the biggest challenges for the Gutenberg contributors: to put in […]

    Reply

  18. […] itself: because blocks are registered in the frontend, unregistering an already-registered block is done by loading an additional script. In my opinion, this is one of the biggest challenges for the Gutenberg contributors: to put in […]

    Reply

  19. […] itself: because blocks are registered in the frontend, unregistering an already-registered block is done by loading an additional script. In my opinion, this is one of the biggest challenges for the Gutenberg contributors: to put in […]

    Reply

  20. […] itself: because blocks are registered in the frontend, unregistering an already-registered block is done by loading an additional script. In my opinion, this is one of the biggest challenges for the Gutenberg contributors: to put in […]

    Reply

  21. […] itself: because blocks are registered in the frontend, unregistering an already-registered block is done by loading an additional script. In my opinion, this is one of the biggest challenges for the Gutenberg contributors: to put in […]

    Reply

  22. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

  23. […] itself: because blocks are registered in the frontend, unregistering an already-registered block is done by loading an additional script. In my opinion, this is one of the biggest challenges for the Gutenberg contributors: to put in […]

    Reply

  24. […] method described by Jason Bahl might be of interest:https://jasonbahl.com/2018/05/29/whitelisting-blacklisting-blocks/By his own admission, it’s quite possibly a fragile method – this article’s over a […]

    Reply

  25. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

  26. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

  27. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

  28. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

  29. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

  30. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

  31. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

  32. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

  33. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

  34. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

  35. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

  36. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

  37. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

  38. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

  39. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

  40. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

  41. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

  42. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

  43. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

  44. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

  45. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

  46. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

  47. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

  48. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

  49. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

  50. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

  51. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

  52. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

  53. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

  54. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

  55. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

  56. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

  57. […] because blocks are registered within the frontend, unregistering an already-registered block is accomplished by loading an additional script. Individually, that is undoubtedly one of the most largest challenges for the Gutenberg […]

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.