Reusable blocks are great! But they can be a problem. Sadly there is no neat off button, but we can get very close.
Why remove them? On a shared site with user created content, reusable blocks could be modified and manipulated maliciously. It might also be a moderation concern, with users creating lewd content in reusable blocks that then appear in the UI.
Removing The Reusable Blocks Tab
Gutenberg adds a reusable blocks tab to the inserter that looks like this:
After some digging, it appears that this tab does not have an off switch or tooggle, but it only shows if there are reusable blocks to select. This is also true of block patterns.
The list of reusable blocks is stored in the block editors main settings object in the __experimentalReusableBlocks
key. We can fool the editor into believing this is the case with this javascript snippet:
wp.data.dispatch('core/block-editor').updateSettings( { __experimentalReusableBlocks: [] } )
Now that there are no reusable blocks in the settings, the tab immediately disappears:
But what if a new reusable block is created? What if the editor makes a request to the API and discovers the truth? We can enforce the lie by subscribing to the main data store with this javascript:
// Erase the existence of any reusable blocks.
wp.data.subscribe( () => {
const settings = wp.data.select( 'core/block-editor' ).getSettings();
if ( settings.__experimentalReusableBlocks && settings.__experimentalReusableBlocks.length > 0 ) {
wp.data.dispatch('core/block-editor').updateSettings( { __experimentalReusableBlocks: [] } );
}
});
By using subscribe
our function is called whenever the data store is changed. We then fetch the settings, check for reusable blocks, and reset it if needed. Without the if
statement, our dispatch
would cause an infinite loop ( I realise in hindsight it might not be necessary to check the length as WP will only notify listeners if the store values change ).
What About Adding Reusable Blocks?
I spent some time trying to figure this out. Capabilities for reusable blocks ( wp_block
are set to those of the post
so they can’t be filtered specifically, and the meta capabilities have unique handling of block capabilities that replace them with post equivalents. I even considered filtering post insertion to prevent their creation, but this would still leave the Add to reusable blocks user interface that can’t be hidden with CSS:
Thankfully, when registering a block, you can declare that it does or does not support various features, e.g. HTML editing, can it have multiple instances, does it support full width, etc. One of these is if the block can be made reusable or not.
To exploit this, I added a filter to block registration, and forced all blocks to be non-re-usable:
/**
* Remove supported features from all blocks
*
* @param {*} settings
* @param {*} name
*/
function filterBlockSupports( settings, name ) {
// ensure there is a supports section
if ( undefined == settings.supports ) {
settings.supports = {}
}
settings.supports.reusable = false;
return settings;
}
wp.hooks.addFilter( 'blocks.registerBlockType', 'tomjn/disable-reusability', filterBlockSupports );
The Last Traces of UI
There is one last location for the reusable blocks UI in the main menu in the top right:
While this anchor tag doesn’t have a CSS selector, it does lead to an admin page, and we can select the href
attribute to hide it:
.components-menu-item__button[href="edit.php?post_type=wp_block"] {
display: none;
}
With this, all traces are removed. Currently no keyboard shortcuts are listed for creating reusable blocks, but reusable blocks already in content will need to be removed, and can be copy pasted into place.
Putting it All Together
If we put this all together, we get this plugin:
<?php
/**
* Plugin Name: Disable Reusable blocks
* Plugin URI: https://tomjn.com/2021/04/05/turning-off-reusable-blocks/(opens in a new tab)
* Description: Hides the reusable blocks interface in the block editor
* Author: Tom J Nowell
* Author URI: https://tomjn.com
* License: GPLv2
* Version: 1.0
* Requires at least: 5.2
* Requires PHP: 7.2
*/
/**
* Disable reusable blocks.
*
* @return void
*/
function tomjn_disable_reusable_blocks() : void {
$js = <<<JSCODE
wp.domReady( function() {
wp.data.dispatch('core/block-editor').updateSettings( { __experimentalReusableBlocks: [] } );
wp.data.subscribe( () => {
const settings = wp.data.select( 'core/block-editor' ).getSettings();
if ( settings.__experimentalReusableBlocks && settings.__experimentalReusableBlocks.length > 0 ) {
wp.data.dispatch('core/block-editor').updateSettings( { __experimentalReusableBlocks: [] } );
}
});
/**
* Remove supported features from all blocks
*
* @param {*} settings
* @param {*} name
*/
function filterBlockSupports( settings, name ) {
// ensure there is a supports section
if ( undefined == settings.supports ) {
settings.supports = {}
}
settings.supports.reusable = false;
return settings;
}
wp.hooks.addFilter( 'blocks.registerBlockType', 'tomjn/disable-reusability', filterBlockSupports );
} );
JSCODE;
$css = <<<CSSCODE
.components-menu-item__button[href="edit.php?post_type=wp_block"] {
display: none;
}
CSSCODE;
wp_add_inline_script(
'wp-block-editor',
$js
);
wp_add_inline_style(
'wp-block-editor',
$css
);
}
add_action( 'enqueue_block_editor_assets', 'tomjn_disable_reusable_blocks' );
Now that you’ve removed reusable blocks, why not remove the block directory install prompts too?
Pingback: WP Weekly 40 / Noise / Headphones, Speed Focus, Celebrity WP Websites