There's no clear way of disabling the Block Directory. I expect sites will want to control whether the Block Directory is available, and to be disable it if desired. I would like to disable it on some of my sites.
I propose that the Block Directory provide a way for it to be disabled entirely in code. A filter or constant are likely a good fit.
It's possible to prevent the Block Directory assets from being enqueued:
function disable_block_directory() {
remove_action( 'enqueue_block_editor_assets', 'gutenberg_enqueue_block_editor_assets_block_directory' );
}
add_action( 'plugins_loaded', 'disable_block_directory' );
_UPDATE: The following details are only accurate under certain circumstances. See https://github.com/WordPress/gutenberg/issues/23961#issuecomment-659500445 for details._
However, this is not a documented way of disabling the feature has unintended consequences. In this case, the "no blocks found" message is removed:
| With Block Directory | Without |
| --- | --- |
| |
|
More implementation details…
It's difficult to restore the "no blocks found" functionality because an experimental API __experimentalInserterMenuExtension
handles it:
I worked up a solution that may help inform the necessary changes. Note that this depends on __experimentalInserterMenuExtension
(like the Block Directory itself) so isn't suitable for widespread use.
function block_directory_empty_results() {
wp_enqueue_script( /* Enqueue the JavaScript below… */ );
}
function disable_block_directory() {
remove_action( 'enqueue_block_editor_assets', 'gutenberg_enqueue_block_editor_assets_block_directory' );
add_action( 'enqueue_block_editor_assets', 'block_directory_empty_results' );
}
add_action( 'plugins_loaded', 'disable_block_directory' );
var wp = window.wp;
var __ = wp.i18n.__
var registerPlugin = wp.plugins.registerPlugin
var __experimentalInserterMenuExtension = wp.blockEditor.__experimentalInserterMenuExtension
var createElement = wp.element.createElement;
// Check if the experimental slot is available before registering the plugin.
if ( typeof __experimentalInserterMenuExtension !== 'undefined' ) {
registerPlugin( 'disable-block-registry', {
render: function() {
return createElement( __experimentalInserterMenuExtension, {},
function( props ) {
var hasItems = props.hasItems;
var filterValue = props.filterValue;
if ( hasItems || ! filterValue ) {
return null;
}
return (
createElement('div', {},
createElement(
'p',
{ style: {
padding: 0,
margin: '112px 0',
textAlign: 'center',
color: '#606a73',
} },
/* translators: Displayed when block search returns no results. */
__( 'No blocks found in your library.' )
)
)
);
}
);
}
} );
}
Inspiration:
https://github.com/WordPress/gutenberg/blob/0ac90749e99efe1871dd017fadad25e0ef80cd02/packages/block-directory/src/plugins/inserter-menu-downloadable-blocks-panel/index.js#L23-L42
https://github.com/WordPress/gutenberg/blob/04a792466f9fb48cc82ebeb0a556ccec21223a63/packages/block-directory/src/components/downloadable-blocks-panel/index.js#L43-L45
The information I've provided so far is not entirely correct. It turns out that other functionality in my case was also using __experimentalInserterMenuExtension
. If anything goes into that slot, the default "no results" behavior is not shown. If I disable the block directory and nothing else is rendered into the slot, this is what I see:
This makes for an interesting question around __experimentalInserterMenuExtension
- as a slot, multiple things can be rendered there and may cause the results reporting to either be omitted or duplicated.
I'm not sure if there's a great way to improve this API, it's an advanced feature and exposes some functionality that it's clearly fragile if not used carefully. Thanks to @mcsf for feedback and help debugging.
👋 @StevenDufresne — this issue may be relevant for you.
the block directory is written as an extension so I think the unregistering is a good way to disable it.
But I feel if there's no fill registered for the slot, the "No blocks" found should definitely appear, and I'd consider this as a bug.
… if there's no fill registered for the slot, the "No blocks" found should definitely appear, and I'd consider this as a bug.
If the Block Directory is enabled, it handles the empty results case and the default is not show. The problem I encountered was when the Block Directory was disabled but the slot wasn't empty. With a slot, there can be 0, 1, or _multiple_ things in the slot. 0 seems to work as expected. However, when multiple things can go into the slot, it's unclear how they should coordinate to handle results messaging.
In fixing the missing style issue, I added a similar hook to core, so this _should_ be all that's needed to disable the block directory:
add_action(
'plugins_loaded',
function() {
remove_action( 'enqueue_block_editor_assets', 'wp_enqueue_block_editor_assets_block_directory' );
remove_action( 'enqueue_block_editor_assets', 'gutenberg_enqueue_block_editor_assets_block_directory' );
}
);
The issue of the "no results" message still stands though.
I think for @sirreal's problem, the hook seems reasonable.
I think we may also want a no code approach as well. Maybe a checkbox in the Block Manager
or an option in the Options
menu?
I don't think we need a UI solution, most people will be fine with having the Block Directory enabled (or using the hook). Maybe it's something to revisit, but if enough people want to disable the Block Directory that we want UI for it, we've probably done something wrong 😅
My own take:
remove_action
, as suggested in previous comments, seems totally adequate.__experimentalInserterMenuExtension
is a fairly specific / advanced API, so it's a bit "use at your own risk". I don't think it's necessarily wrong to delegate the responsibility to show the "No results found" view if a site has custom pieces tapping into the interface. But I'm open to improvements.
- Preventing registration using
remove_action
, as suggested in previous comments, seems totally adequate.- I would also avoid a UI solution. There will always be micro-plugins for people who want to explicitly disable the Directory, as has always been the case in WordPress.
I agree with these two points (this does not imply disagreement with the third point). I would add:
remove_action
approach documented and therefore officially supported in some way.This implies a degree of stability. The block editor should continue to without any negative side effects. Any issues with the block editor when using this approach would be considered regressions.
This is fair. It should be fairly easy to add an E2E test with an accompanying WP plugin. The plugin would disable the Block Directory. The test would assert the bare minimum: that the editor loads with no errors, that searching in the Inserter for a known core block returns said block, and that searching for something else yields the _No blocks found_ message.
I don't think we need a UI solution, most people will be fine with having the Block Directory enabled (or using the hook). Maybe it's something to revisit, but if enough people want to disable the Block Directory that we want UI for it, we've probably done something wrong 😅
I would also avoid a UI solution. There will always be micro-plugins for people who want to explicitly disable the Directory, as has always been the case in WordPress.
Fair enough. With that being said, I wonder how the other options made it in?
so this _should_ be all that's needed to disable the block directory
Should this still work to disable the block directory? I've attempted both via theme and plugin and can't get it to change the behaviour when searching blocks with WP5.5-RC1-48681.
The function name was changed before merging, so the actual code you should use is this:
add_action(
'plugins_loaded',
function() {
remove_action( 'enqueue_block_editor_assets', 'wp_enqueue_editor_block_directory_assets' );
remove_action( 'enqueue_block_editor_assets', 'gutenberg_enqueue_block_editor_assets_block_directory' );
}
);
@sirreal Anything left to do here?
We seem to have settled on an accepted approach for disabling the Block Directory. Has it been officially documented somehow? That still seems important.
Documentation is definitely welcome!
Is anyone able to confirm this still works in WP 5.5.1? Using the code snippet that @ryelle posted does not disable the Block Directory for me. All the of the blocks are still present.
On another related note, is there a way to disable specific blocks from the Block Directory as there is with disabling Gutenberg blocks from the editor using add_filter('allowed_block_types')
?
@gpsugy are you using the recommended approach in the handbook? That does seem to work.
add_action(
'plugins_loaded',
function() {
remove_action( 'enqueue_block_editor_assets', 'wp_enqueue_editor_block_directory_assets' );
remove_action( 'enqueue_block_editor_assets', 'gutenberg_enqueue_block_editor_assets_block_directory' );
}
);
@sirreal This is actually the same snippet of code I was referencing, and it is not working for me. For a second I thought it was working, but that was only because I tried opening the Block Directory in a custom post type (which led to a new discovery that the Block Directory does not work with custom post types by default).
My setup PHP file involves usage of add_action(enqueue_block_editor_assets)
to register theme assets with the block editor. Perhaps the snippet of code you posted does not work compatibly with that?
My setup PHP file involves usage of
add_action(enqueue_block_editor_assets)
to register theme assets with the block editor. Perhaps the snippet of code you posted does not work compatibly with that?
Not sure if this might be your issue, but as I previously noted here, this code won't work within themes since theme setup happens after the plugins_loaded
hook has fired. You'll want to instead hook into admin_init
.
@uamv I am indeed utilizing a theme; thank you for that helpful reply, and it is likely the reason for my issue. Having trouble with getting that to work, however. Hooking into admin_it
still requires usage of add_action
, correct? If so, there seems to be an order of when this snippet of code is supposed to run in relation to other hooks that I am unaware of. Could you please specify?
In a theme, you should be able to just add the remove_action
calls directly, without putting it in a hook.
remove_action( 'enqueue_block_editor_assets', 'wp_enqueue_editor_block_directory_assets' );
remove_action( 'enqueue_block_editor_assets', 'gutenberg_enqueue_block_editor_assets_block_directory' );
Yep. Directly removing should work. And, to clarify, if you did want to have it hooked, admin_init
should work – I see you mention admin_it
above, which wouldn't fire anything.
Ah, my apologies. I actually meant admin_init
, but misspelled it as admin_it
. This is very strange... I inserted the following code snippet
remove_action( 'enqueue_block_editor_assets', 'wp_enqueue_editor_block_directory_assets' );
remove_action( 'enqueue_block_editor_assets', 'gutenberg_enqueue_block_editor_assets_block_directory' );
in the hook, add_action('init')
, along with after that hook further down in my setup PHP file - yet no success. I have also tried the following, which did not work for me:
add_action(
'admin_init',
function() {
remove_action( 'enqueue_block_editor_assets', 'wp_enqueue_editor_block_directory_assets' );
remove_action( 'enqueue_block_editor_assets', 'gutenberg_enqueue_block_editor_assets_block_directory' );
}
);
(I have also tried replacing admin_init
with plugins_loaded
, which was also unsuccessful.)
I am using a Sage Roots framework, if that perhaps sheds any light as to why this is not working for me. After all of this, clicking "Browse All" in the gutenberg editor still opens up the left sidebar Block Directory.
Is there a way to specifically disable specific blocks from the Block Directory? That should suffice as an alternative (and better) solution.
@gpsugy I think there might be some confusion here about what the Block Directory is. The left sidebar is the block inserter. The block directory is a part of the block inserter that is used to display suggestions for blocks to install from WordPress.org.
As far as I know, there is no way to completely disable the block inserter.
If you want to hide specific blocks, you can use the allowed_block_types
filter that is documented here.
@TimothyBJacobs, thank you for the clarification. What I was thinking to be the Block Directory was indeed the Block Inserter. Referencing the allowed_block_types
filter is also greatly appreciated. Thank you to everyone who helped in resolving my questions!
Most helpful comment
The function name was changed before merging, so the actual code you should use is this: