-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Fix presets data for themes that do not provide any preset #36054
Conversation
I've got this thought: for the backward-compatible theme settings we retrofit plugins can still filter them via |
82d9913
to
13685c7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I'm not wrong, this change means that all add_theme_support
calls are ignored when constructing the "theme" global styles.
For me, it seems that it's not the right approach. My expectation is the following:
- add_theme_support calls should be taken into consideration when building the "theme" global styles.
- block_editor_settings should not be taken into consideration.
I tried following the code but I think the issue comes from the fact that the current code base is optimized for this flow:
theme-supports ----(transform)----> block-editor-settings -----( merge with raw theme.json )------> theme global styles
It seems that the solution should be that we do this instead
theme-supports --------( merge with raw theme.json ) -----> theme global styles.
Does that make sense?
I guess in other words, |
Yeah, exactly, that's what this PR should do. It is a change from how it worked until now but we need it to make the UI color control work as we want (show all origins but only if they have data). Plugins that were filtering the theme support settings we retrofit in Before this is ready, I still need to understand why some tests needed changing. |
* @param string $origin To what level should we merge data. | ||
* Valid values are 'theme' or 'user'. | ||
* Default is 'user'. | ||
* | ||
* @return WP_Theme_JSON_Gutenberg | ||
*/ | ||
public static function get_merged_data( $settings = array(), $origin = 'user' ) { | ||
public static function get_merged_data( $origin = 'user' ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change is great :)
* So we take theme supports, transform it to theme.json shape | ||
* and merge the self::$theme upon that. | ||
*/ | ||
$theme_support_data = WP_Theme_JSON_Gutenberg::get_from_editor_settings( gutenberg_get_default_block_editor_settings() ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you help me understand what this line does? My understanding is the following: it uses the "add_theme_support" calls to build something like a "theme.json" tree based on these.
If that's correct, then we're aligned here. The thing that bother me though is that it still says "editor settings", it should be more something like:
$theme_support_data = WP_Theme_JSON_Gutenberg::get_from_theme_supports();
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that's exactly what it does.
The current name is actually representative of what this function does at the moment, as gutenberg_get_default_block_editor_settings
returns editor settings. However, I understand your point is that you'd rather inline the call to theme supports into WP_Theme_JSON
.
This makes me think of the conversation about the endpoint and whether to allow getting data for the non-active themes. How can we retrieve the theme supports data of a non-active theme? Does the REST API request load the theme being requested? Or we won't have access to that data?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, I guess for now, we'll limit that endpoint to the active theme. I think it's fine for our current usage.
@@ -142,7 +111,7 @@ function_exists( 'gutenberg_is_edit_site_page' ) && | |||
} | |||
|
|||
// Copied from get_block_editor_settings() at wordpress-develop/block-editor.php. | |||
$settings['__experimentalFeatures'] = $consolidated->get_settings(); | |||
$settings['__experimentalFeatures'] = gutenberg_get_global_settings(); | |||
|
|||
if ( isset( $settings['__experimentalFeatures']['color']['palette'] ) ) { | |||
$colors_by_origin = $settings['__experimentalFeatures']['color']['palette']; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All the changes here make things a lot simpler, it's cool and also validates these higher level APIs.
0ec76f8
to
6d9098c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking good to me, I think we should be looking at removing the get_from_editor_settings
function in favor of a get_from_theme_supports
for clarity. But that's not a blocker.
Do not read them from the filtered block settings. This has the side-effect of not taking into account changes 3rd parties may have done to theme supports data. For example, adding support for link color, or changing the theme editor palette.
6d9098c
to
76f61ab
Compare
'color' => array( | ||
'palette' => array( | ||
'color' => array( | ||
'custom' => false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These tests now get the defaults for color.custom
, color.customGradients
, typography.customFontSize
, typography.customLineHeight
, spacing.units
, and spacing.customPadding
.
The reason is that the (legacy) theme supports are now pulled from the WP_Theme_JSON_Resolver_Gutenberg::get_theme_data()
method directly, while, before, these were passed via an argument (and it was empty for the tests).
Apparently, some PRs got merged in parallel and not all the uses of |
This is a dormant bug that was uncovered by #35970 (comment)
The bug
In the
core/block-editor
store, we have the presets keyed by origin (core, theme, user). For example, the color palette is stored under__experimentalFeatures.color.palette
as:If a given origin has not provided data, there's no key for them. For themes that do not provide any preset and the user hasn't either, the presets are expected to have this shape:
Storefront is one of those themes that do not provide any preset so should be expected to have the above shape. The same can be reproduced for any theme that has a
theme.json
by removing thesettings.color.palette
contents. By testing #35970 (comment) we found that these themes included in the theme origin the same data that already was in the core one:How to test
settings.color.palette
property.core/block-editor
store, specifically thesettings.__experimentalFeatures.color.palette
key.Why it happens
WordPress 5.8 does the following (see get_block_editor_settings):
1.1. Takes the data from the theme (either from theme supports or theme.json).
1.2 It stores under
settings.__experimentalFeatures
the theme.json settings.1.3. For backward compatibility, it also retrofits the data to the legacy settings mechanism (
settings.colors
for the palette,settings.gradients
for the gradients, and so on). At this point, all themes have stored presets in the old legacy settings mechanism, whether it's core presets or presets coming from the theme.1.4. Then, it fires the block editor settings filter, so 3rd parties can filter them.
The Gutenberg plugin hooks into that filter to reorganize the
settings.__experimentalFeatures
with the new schema and then retrofit again the data to the legacy settings mechanism. The bug is here, in the plugin. Because we use the filtered legacy settings (settings.color
) to create the new ones (settings.__experimentalFeatures.color.palette
) there's always data coming fromsettings.color
that we interpret as coming from the "theme origin".The fix is not taking into account the filtered legacy settings (
settings.color
).The drawback to this fix is that the legacy settings can be filtered no longer, because the plugin will ignored them anyway.
For reference, there're less than a dozen, see here.