Make WordPress Core

Opened 2 years ago

Closed 2 years ago

Last modified 2 years ago

#55301 closed enhancement (fixed)

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

Reported by: noisysocks's profile noisysocks Owned by: noisysocks's profile noisysocks
Milestone: 6.0 Priority: normal
Severity: normal Version:
Component: Editor Keywords: has-patch has-unit-tests needs-dev-note
Focuses: Cc:

Description

Copied from https://github.com/WordPress/gutenberg/issues/28517. See discussion there.

---

## 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.

https://github.com/woocommerce/woocommerce-gutenberg-products-block/pull/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.

Change History (15)

This ticket was mentioned in PR #2374 on WordPress/wordpress-develop by noisysocks.


2 years ago
#1

  • Keywords has-patch has-unit-tests added; needs-patch removed

Trac ticket: https://core.trac.wordpress.org/ticket/55301

### What this is

Adds new WP_Block_Editor_Context::$type and WP_Block_Editor_Context::$is_customizer fields. This allows plugin developers to tell which block editor is being loaded when using filters such as allowed_block_types_all and block_editor_rest_api_preload_paths.

### How to test

Here's some code you can put into e.g. wp-content/mu-plugins/allowed-blocks.php:

{{{php
add_filter(

'allowed_block_types_all',
function( $allowed_block_types, $block_editor_context ) {

if ( 'widgets' === $block_editor_context->type ) {

return array( 'core/paragraph', 'core/heading' );

}
return $allowed_block_types;

},
10,
2

);
}}}

#2 @noisysocks
2 years ago

  • Keywords needs-dev-note added

talldan commented on PR #2374:


2 years ago
#3

The part I'm most unsure about here is is_customizer, which seems very specific to the widgets use case. WP_Block_Editor_Context maybe shouldn't be that specific.

If the widget editor type values are changed to customize-widgets or edit-widgets, at least someone implementing a filter can do something like this:
{{{php
add_filter(

'allowed_block_types_all',
function( $allowed_block_types, $block_editor_context ) {

if (

'customize-widgets' === $block_editor_context->type

'edit-widgets' === $block_editor_context->type

) {

return array( 'core/paragraph', 'core/heading' );

}
return $allowed_block_types;

},
10,
2

);
}}}

However, I'm not sure if type is the correct semantic if that naming is used.

draganescu commented on PR #2374:


2 years ago
#4

I agree with @talldan we should only rely on $type. The $is_customizer flag seems redundant.

noisysocks commented on PR #2374:


2 years ago
#5

If the widget editor type values are changed to customize-widgets or edit-widgets, at least someone implementing a filter can do something like this:

I did consider this but I don't like it 😅

API design should nudge developers towards doing the right thing. I want developers to configure the block editor exactly the same way for the widgets editor in the widgets screen and the widgets editor in the customizer. They are the same editor and so should provide the same user experience. By having both type and is_customizer, it makes it slightly more difficult for developers to do the wrong thing and configure both editors differently. By having only type, it makes it slightly more difficult for developers to do the right thing and configure both editors the same.

The part I'm most unsure about here is is_customizer, which seems very specific to the widgets use case. WP_Block_Editor_Context maybe shouldn't be that specific.

I'd argue that $is_customizer isn't _that_ specific to the widget use case as I could imagine that a block editor may one day be rendered in the Customizer for some other purpose e.g. to edit a post or page.

Moreover, WP_Block_Editor_Context already has $post which is very specific to type = 'post'.

Ideally I think WP_Block_Editor_Context should be a base class with subclasses to denote the editor type.

{{{php
abstract class WP_Block_Editor_Context {
}
class WP_Post_Block_Editor_Context extends WP_Block_Editor_Context {

public $post;

}
class WP_Widgets_Block_Editor_Context extends WP_Block_Editor_Context {

public $is_customizer;

}
class WP_Site_Block_Editor_Context extends WP_Block_Editor_Context {
}
}}}

We can't do this though as it requires renaming WP_Block_Editor_Context to WP_Post_Block_Editor_Context which would break backwards compatibility.

So instead I'm leaning into WP_Block_Editor_Context being a wrapper around an array that really only exists for type hinting purposes.

talldan commented on PR #2374:


2 years ago
#6

I'd argue that $is_customizer isn't that specific to the widget use case as I could imagine that a block editor may one day be rendered in the Customizer for some other purpose e.g. to edit a post or page.

My feeling on this isn't particularly strong, I just think this is based on a use case of one, and there are no concrete plans to add more customizer editors. Usually we work on the basis of being terrified by future maintainability, so it seems a little outside the norm to be this bold.

Anyway, our editors are a bit weird, and I don't think names or types really mean that much. We have one 'post' editor that is used to also edit pages and any custom post type. We have a site editor that can literally edit anything and allowed blocks won't mean very much there. Then we have two widget editors that can only edit the same individual type of thing. If anything it might be best to work on the basis the data type being edited (which is I suppose what $post tried to do).

There's no real consistency, so we're probably only able to implement something with trade-offs. I think that's why a prefer to use names that are already in regular usage (core/edit-post, core/edit-site etc.). Plugin devs might already be familiar with these terms.

noisysocks commented on PR #2374:


2 years ago
#7

I do like that core/edit-post, core/edit-site, etc. leaves room for plugin authors to use block context by setting the name to woocommerce/product or whatever.

noisysocks commented on PR #2374:


2 years ago
#8

Let's make @draganescu decide 😛

gziolo commented on PR #2374:


2 years ago
#9

Waiting for Andrei to decide... 🍿 🦗

Ideally I think WP_Block_Editor_Context should be a base class with subclasses to denote the editor type.

Yes, that would work, too. It would be a bit harder to document it though because you would have 5 class names with different class properties. In the future, we might also have a site editor context that allows editing post content that will require $post so it's hard to predict the implications.

noisysocks commented on PR #2374:


2 years ago
#10

OK, I updated this to use $name. Semantically it's all the same. I like that this means there's consistency between the strings you see in WP_Block_Editor_Context::$name and the strings you see in wp.data.

noisysocks commented on PR #2374:


2 years ago
#11

I opened https://github.com/WordPress/gutenberg/pull/39299 in the Gutenberg repo to compliment this PR. It usages some usages of WP_Block_Editor_Context in the plugin to pass an appropriate $name.

#12 @noisysocks
2 years ago

  • Owner set to noisysocks
  • Resolution set to fixed
  • Status changed from new to closed

In 52942:

Add WP_Block_Editor_Context::$name

Adds a new WP_Block_Editor_Context::$name and field. This allows plugin
developers to tell which block editor is being loaded when using filters such as
allowed_block_types_all and block_editor_rest_api_preload_paths.

Fixes #55301.
Props talldanwp, gziolo, andraganescu.

joyously commented on PR #2374:


2 years ago
#14

Is this available on the 'enqueue_block_editor_assets' action?

talldan commented on PR #2374:


2 years ago
#15

@joyously It doesn't look like it as that action doesn't seem to receive the block editor context:
https://github.com/WordPress/wordpress-develop/blob/0fb4f900304c712cf7a7626cd069ea1b90bda99e/src/wp-admin/edit-form-blocks.php#L265

It may be possible to add it—I'd recommend making a core trac ticket.

Note: See TracTickets for help on using tickets.