Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide an API to prevent certain blocks being shown in Widget Areas #28517

Closed
mikejolley opened this issue Jan 27, 2021 · 16 comments
Closed

Provide an API to prevent certain blocks being shown in Widget Areas #28517

mikejolley opened this issue Jan 27, 2021 · 16 comments
Labels
[Feature] Extensibility The ability to extend blocks or the editing experience [Feature] Widgets Customizer Ability to add and edit blocks in Customize → Widgets. [Feature] Widgets Screen The block-based screen that replaced widgets.php. Needs Dev Ready for, and needs developer efforts [Package] Edit Widgets /packages/edit-widgets [Type] Enhancement A suggestion for improvement.

Comments

@mikejolley
Copy link
Contributor

What problem does this address?

With the introduction of Widget Areas, Gutenberg assumes all existing blocks will work in this context. We have a use case where some blocks may not work as widgets, or may conflict with legacy widgets or things such as shortcodes.

woocommerce/woocommerce-blocks#3737

Gutenberg does provide the widgets_to_exclude_from_legacy_widget_block filter, but this only works on widgets.

Unlike in the post editor screen (which provides allowed_block_types ) there doesn't appear to be an filter, supports variable, or any API we can use to state that a block should not appear in this context.

What is your proposed solution?

Some form of supports flag when the block is registered, or an allow/denylist where the block can be excluded from the widget area block inserter.

Our current solution/workaround is to check if 'themes.php' === $pagenow and not register the block.

@mtias mtias added [Feature] Widgets Screen The block-based screen that replaced widgets.php. [Package] Edit Widgets /packages/edit-widgets labels Jan 27, 2021
@draganescu draganescu added [Feature] Extensibility The ability to extend blocks or the editing experience [Type] Enhancement A suggestion for improvement. labels Feb 18, 2021
@noisysocks
Copy link
Member

noisysocks commented May 17, 2021

Perhaps we can add widgets_allowed_block_types which accompanies the block editor's allowed_block_types.

Or maybe allowed_block_types-$pagenow? Not sure on best naming. Let's see what the Site Editor does here if anything.

@mikejolley
Copy link
Contributor Author

I like the first suggestion (widgets_allowed_block_types) as that would let us specifically target this use-case separately from the editor. Either works though :)

@draganescu
Copy link
Contributor

Adding this later would come after people add the unallowed blocks already :)

@noisysocks
Copy link
Member

noisysocks commented Jul 7, 2021

With the introduction of allowed_block_types_all I think the correct solution here is to pass a subclass of WP_Block_Editor_Context that is specific to the widget editors to that filter.

add_filter( 'allowed_block_types_all', function( $allowed_block_types, $block_editor_context ) {
	if ( $block_editor_context instanceof WP_Widgets_Block_Editor_Context ) ) {
		// This is a widgets block editor.
	}
	return $allowed_block_types;
} );

We will need to implement this. It's a good candidate for 5.8.x, as it's very late in the 5.8 release cycle right now. For now one can use $pagenow as per #33238 (comment).

@michaelbourne
Copy link

The Woocommerce workaround is good for me for now but a core solution would be ideal. If anyone hasn't seen it linked above, it relies on a simple $pagenow check, which can be used to also remove blocks from the widget/customizer context.

woocommerce/woocommerce-blocks#4225

@noisysocks noisysocks added the Needs Dev Ready for, and needs developer efforts label Jan 27, 2022
@noisysocks
Copy link
Member

Definitely need to sort this out now that there are three block editors (post, widgets, site). Relying on $pagenow is a bit obtuse.

@noisysocks
Copy link
Member

Related to this is a good suggestion made by @myleshyson in #34788 about building an API for this into register_sidebar.

register_sidebar( [
    'name'            => __( 'Primary Sidebar', 'theme_name' ),
    'allowed_blocks'  => [ 'core/paragraph', 'core/latest-posts' ]
] );

@thomasplevy
Copy link
Contributor

I'd just like to note my 2 cents is that an allowed block list is terribly difficult to maintain if the desire is to have a single block that isn't allowed in any widget areas at all.

For example: I have a block I'd like to denote can only be used on a specific post type and not in widget areas. In order to filter this using an allow-list I need to compile a list of all other blocks in existence (and possible existence, for extensibility support) and then remove my block from it.

I don't think allow lists are terrible in general and could be very useful if I have a specific widget area I'd like to specify only allowing specific blocks but I don't think it's a viable solution for the problem raised in this thread.

@myleshyson
Copy link
Contributor

I think on the other hand, an allow list does protect against unintentional blocks from showing in a widget area. Our context at UF is probably different since we manage sites for editors, but with an allow list we don't have to worry about unaccounted for blocks showing up in a widget area whenever WordPress updates. I'm sure agencies have some of the same worries, and probably why the other block filter apis in WordPress also use allow lists.

I think you also have the same problem with a deny list. If you only want to allow 2 blocks, and there's 30 blocks defined, now you have to add 28 blocks to that deny list. It's worse though because you also have to account for blocks that come via an update that don't currently exist. If a new block is added via an update, you may face unexpected behavior when an editor uses that block in an area that didn't account for it. With an allow list that's not a concern.

@noisysocks
Copy link
Member

noisysocks commented Feb 17, 2022

There was a proposal a long long while back for having properties such as allowedBlocks accept objects where you could allow or deny specific block types.

<InnerBlocks
	allowedBlocks={ {
		'core/paragraph': true, // Paragraphs are allowed.
		'core/more': false, // More is not allowed.
		'*': true, // Everything else is allowed.
	} }
/>

It never got much traction at the time (too complicated) but maybe we can think about adding something like that now.

Perhaps a simpler alternative is to just have disallowedBlocks in addition to allowedBlocks. It's not clear which one would take precedence, though.

I think let's ticket all of that separately, as it affects more than just widget areas (CPTs, InnerBlocks, etc.), and just focus on #28517 (comment) for now.

@noisysocks
Copy link
Member

I'm working on implementing something similar to #28517 (comment). It will be entirely in Core so let's close this issue in favour of a Trac ticket: https://core.trac.wordpress.org/ticket/55301

@noisysocks
Copy link
Member

Just closing the loop on this...

https://core.trac.wordpress.org/ticket/55301 has been closed and you'll be able to access $context->name in WordPress 6.0 to achieve this.

add_filter(
	'allowed_block_types_all',
	function( $allowed_block_types, $block_editor_context ) {
		if ( 'core/edit-site' === $block_editor_context->name ) {
			return array( 'core/paragraph' );
		}
		if ( 'core/edit-widgets' === $block_editor_context->name ) {
			return array( 'core/heading' );
		}
		if ( 'core/customize-widgets' === $block_editor_context->name ) {
			return array( 'core/image' );
		}
		if ( 'core/edit-post' === $block_editor_context->name ) {
			return array( 'core/separator' );
		}
		return $allowed_block_types;
	},
	10,
	2
);

@thomasplevy
Copy link
Contributor

this looks great thanks @noisysocks

@skysarwer
Copy link

Hi @noisysocks ,

Do you know if the sub-item described in #34788 was included in this issue release? Could not find the allowed_blocks parameter in the register_siderbar() codex page. Just checking as it would be extremely useful for an upcoming phase in my project. Thank you!

@noisysocks
Copy link
Member

Hi @skysarwer. register_sidebar does not have an allowed_blocks param, no. You'll have to use allowed_block_types_all.

@myleshyson
Copy link
Contributor

myleshyson commented Aug 23, 2022

it doesn't seem like allowed_blocks_all addresses #34788. That issues was for restricting blocks per registered widget, not just for restricting blocks between editor contexts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Extensibility The ability to extend blocks or the editing experience [Feature] Widgets Customizer Ability to add and edit blocks in Customize → Widgets. [Feature] Widgets Screen The block-based screen that replaced widgets.php. Needs Dev Ready for, and needs developer efforts [Package] Edit Widgets /packages/edit-widgets [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

No branches or pull requests

8 participants