Fix presets data for themes that do not provide any preset#36054
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.
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. |
| * @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.
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.
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.
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.
Good point, I guess for now, we'll limit that endpoint to the active theme. I think it's fine for our current usage.
| $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.
All the changes here make things a lot simpler, it's cool and also validates these higher level APIs.
0ec76f8 to
6d9098c
Compare
youknowriad
left a comment
There was a problem hiding this comment.
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.
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-editorstore, we have the presets keyed by origin (core, theme, user). For example, the color palette is stored under__experimentalFeatures.color.paletteas: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.jsonby removing thesettings.color.palettecontents. 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.paletteproperty.core/block-editorstore, specifically thesettings.__experimentalFeatures.color.palettekey.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.__experimentalFeaturesthe theme.json settings.1.3. For backward compatibility, it also retrofits the data to the legacy settings mechanism (
settings.colorsfor the palette,settings.gradientsfor 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.__experimentalFeatureswith 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.colorthat 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.