-
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
Allow plugins to include a theme.json file in the same way themes do #41707
Comments
Another example of how this will be useful (for a plugin like WooCommerce) is that the plugin provided I would suggest however that the hierarchy of properties be something like: User > Block > Theme Potential implementation optionsIt looks like we would need to add some 1. Filter for plugin to register The filter would likely be within the 2. Path defined via property in the plugin header Similar to how other plugin details are set in the plugin header, there could be potentially a One advantage of having this in the plugin header is that that is already parsed by WP so it could be an aid to discoverability (only hitting the filesystem for the file if needed). There's also some potential benefits for surfacing this more readily via the WP.org plugin listing (or other automations) as well. 3. Automatic discovery via specific location for file Having a requirement that the Personally, I'm leaning more towards options 2 and 3 (perhaps a combination of both) because it still provides an opt-in path for plugins yet keeps implementation details handled by WordPress. |
I think the plugin should come before the theme as a fallback and be merged into it, given the theme might want to style and control the plugin's blocks specifically, it should supercede if it's targeting those blocks. Any suggestions for how the API might work from a plugin's perspective? The merging is fairly trivial, so it's more about the ergonomics. Consider also that WordPress bundles a theme.json as well for reference. There's been some requests to unload that bundled fallback before, so that also needs to be taken into account. |
Agreed, what I listed in the hierarchy flow is intended to represent priority of control from left to right. So, user overrides blocks which override theme which override plugin (I may be wrong on the blocks -> theme order, I think that might have changed recently?)
I'm not sure what specifically you're asking about here? I'm guessing this isn't a question about how the plugin
Yes, I see that, and the theme takes precedence over anything defined by core's
Unload as in remove it completely, or to have an interface for external control over unloading it? |
Got it, was reading the sequence wrong. Unload as being able to remove it if you want to supply your own without any dependencies or fallbacks. I'm asking how should a plugin register or make its json file available, assuming it'd exist as a separate file. |
That's what I was addressing in my original comment. Ideally I think the plugin shouldn't need to explicitly register it other than maybe an option in the plugin header and then having the
The above would signal to WordPress core when parsing the plugin header on plugin activation/update that:
WordPress core could just register the paths for all plugins indicating they have a |
I love the idea. Two thoughts:
|
This is a fascinating idea. One additional consideration would be merging settings from multiple plugins.
With that, we would also need to figure out how to ensure that settings from multiple plugins are processed and merged in a predictable way.
I don't have a formed opinion about the name of the file. I only wanted to surface potential challenges if we were to use translatable fields. We would have to create the list of translatable fields and implement the extraction of translations from |
The latest comments have raised additional questions. I'm still thinking through this but wanted to at least document them here in case others have answers/thoughts. I definitely think we should keep the initial scope fairly limited, but some of the questions raised could influence the initial structure of this, hence I'm asking.
I'll leave a comment in this issue at some point once I've had a chance to think through the implications for various answers to the above questions. |
It's not that a plugin's I'd love to hear what you think and how it overlaps with your needs here. |
Thanks for sharing the link @luisherranz! I think the approach in #41873 is definitely interesting and especially that it keeps the default styles at the block level for blocks. If I'm understanding things correctly, that means if themes don't define any styles for specific blocks, then the registered default styles from the blocks are used. It also seems like this could potentially be useful for defining style variations at the block level here. This would also resolve the merging issue of multiple plugin-provided What is still unclear at this point is how that might solve for other potential use-cases around a plugin provided
Granted, the above use cases aren't supported in the initial iteration of the PR and it's not clear if they would definitely be needed by plugins or if a plugin provided |
👋 I've take a look at this and see different goals:
For this, I see #34180 as a more promising path. It gives a predictable hierarchy:
Note that, unlike for plugins, all of the existing sources are unique (there's only a single WordPress install, a single block type, a single active theme, a single user preferences). Personally, for settings & styles, I see the existing path as more promising to investigate. Though we haven't done much work since that PR was merged. Perhaps an tracking issue listing and clarifying next steps for that API (trying new blocks, new styles, etc) would help people to be informed about the progress? cc @scruffian @adamziel @MaggieCabrera
We've talked about this a number of times and the conclusion was that if we allow exposing custom things, we won't be furthering the original goal of
|
On the topic of using |
The primary problem we're trying to solve for here is for plugins (such as WooCommerce) to have the ability to define defaults for any blocks and/or templates it provides so that block themes don't have to explicitly support those plugins (but can still override). With #41873 now closed, what alternatives are being explored, besides what's proposed here? I guess what you're proposing is that focus is redirected to something similar to what was in #41873, but that aligns more with what was started in #34180? |
#41873 proposed to move the styles from one key to another and made that key stable. My concerns were that the initial work at #34180 had been partially reverted and no other blocks or styles were using the API yet. If the core blocks don't use the API how do we know it provides value to 3rd-party blocks? I still think we should validate the approach started at #34180 by expanding its use and see how it performs. As an analogy, after the initial explorations with block supports we laid out some next steps and found some limitations that we tracked at #28913 This helped anyone interested to learn about the API, understand its boundaries and help to move it forward. Perhaps if we do something similar that initial work will get more attention and momentum? |
I spent some time investigating what the plugin author can expect when shipping custom blocks. This is what I tested using customised
{
"name": "woo/gutenpride",
"supports": {
"html": false,
"__experimentalBorder": {
"color": true,
"radius": true,
"style": true,
"width": true
},
"typography": {
"lineHeight": true
}
}
} The default setting coming from WordPress Core in https://github.com/WordPress/wordpress-develop/blob/1d456706549ccf4f0cc867b8a17d1dceaabf8a77/src/wp-includes/theme.json#L4-L10
{
"settings": {
"appearanceTools": false,
"border": {
"color": false,
"radius": false,
"style": false,
"width": false
},
"typography": {
"lineHeight": false,
}
}
} That means if the theme doesn't opt in to enable those settings for all blocks, then the plugin doesn't have a simple way to enable those border and typography controls in the UI. In the WordPress Core there is an exception to some blocks to handle border differently:
{
"settings": {
"blocks": {
"core/button": {
"border": {
"radius": true
}
},
"core/pullquote": {
"border": {
"color": true,
"radius": true,
"style": true,
"width": true
}
}
}
}
} However, the challenge is that to update settings for this blocks, the theme needs to explicitly override the same setting using the same syntax with
{
"settings": {
"border": {
"color": false,
"radius": false,
"style": false,
"width": false
}
}
} It won't take effect for the |
The styles are determined using the following hierarchy:
One idea would be to add a few extension points to make it:
|
My experiment continued. I removed some styles from the custom block so they don't override settings in JSON files. I added the following changes to the
{
"name": "woo/gutenpride",
"supports": {
"html": false,
"__experimentalBorder": {
"color": true,
"radius": true,
"style": true,
"width": true
},
"typography": {
"lineHeight": true
},
"__experimentalStyle": {
"typography": {
"fontSize": "4em",
"lineHeight": "4em"
}
}
}
} I also added similar styles in other places to find out how that hierarchy works.
{
"styles": {
"typography": {
"fontSize": "3em",
"lineHeight": "3em"
},
"blocks": {
"woo/gutenpride": {
"typography": {
"fontSize": "3.5em",
"lineHeight": "3.5em"
}
}
}
}
} I also tweaked the
{
"styles": {
"typography": {
"fontSize": "2em",
"lineHeight": "2em"
},
"blocks": {
"woo/gutenpride": {
"typography": {
"fontSize": "2.5em",
"lineHeight": "2.5em"
}
}
}
}
} Those styles get applied in the editor as follows: Block-specific entry in the theme wins. The same styles get applied on the front end a bit different: Theme's general entry wins... It looks like the order of importance in the editor resolves as follows: theme
@adamziel, it's only partially true. It looks like its more nuanced when you define styles targeting individual blocks. They always take precedence over default styles defined in any export default function save( { attributes } ) {
const blockProps = useBlockProps.save();
return <div { ...blockProps }>{ attributes.message }</div>;
} |
I think there's a difference between:
I shared an idea about how that could be expressed here, but there could be other ways to do it: |
I used the following resources when learning about |
I wanted to share a couple of thoughts based on my recent experiments. The There are other use cases discussed that can't be covered with {
"version": 2,
"settings": {
"custom": {
"line-height": {
"body": 1.7,
"heading": 1.3
}
}
}
} It’s something you don’t want to add to every block but add instead once for the custom functionality your plugin built to use it in the CSS provided. You could always define them inside the CSS manually, but it would be nice to let the Global Styles to handle it based on its resolution system. Another example would Block styles defined once for multiple blocks: "styles": {
"typography": {
"fontSize": "var(--wp--preset--font-size--normal)"
}
} Here, the idea from @luisherranz would fit perfectly: "styles": {
"blocks": {
"woo/*": {
"typography": {
"fontSize": "var(--wp--preset--font-size--normal)"
}
}
}
} One final thought. I tend to agree with @adamziel that pointed out to me when we were discussing extending
I think that I have a clear picture now of how the proposal explained by @Aljullu and @nerrad would benefit plugins like Woo that add the whole set of functionalities to the WordPress site. This way you can have default CSS variables, CSS styles, that you can use with custom blocks and templates in your plugin and they are subject to all rules that Global Styles introduce. In case of Woo, the additional benefit is that the plugin can offer default state for any block theme without block themes having to explicitly support Woo. However, they can opt in and reuse some CSS custom properties or presets whenever they want to. Themes can still optionally override that default state if they want. |
#44015 is very relevant as it might allow plugins to effectively define its own theme.json by hooking and modifying. This is a lower level API, but it might allow a pathway to then formalizing registration of theme.json extensions. |
Now, we landed filters for |
I think we can consider this closed and ask plugins attempting to extend to provide feedback on what is working, what isn't, and what possible registration hooks might make sense to reduce boilerplate. |
I have gone ahead and created #45198 to track the next steps for the |
Description
Currently, if a plugin wants to set default styles for its blocks, it can either write the styles in CSS or write them in the block default attributes.
None of these approaches allow themes to easily override the styles of the plugin using
theme.json
.A solution would be to allow plugins to include a
theme.json
file in the same way themes are already doing it. Styles specified in thetheme.json
of a plugin, would have lower priority than the styles from the theme'stheme.json
and user styles.This way, plugins can specify the default styles of their blocks in their
theme.json
and themes can override the styles from theirtheme.json
.Step-by-step reproduction instructions
Screenshots, screen recording, code snippet
No response
Environment info
No response
Please confirm that you have searched existing issues in the repo.
Yes
Please confirm that you have tested with all plugins deactivated except Gutenberg.
Yes
The text was updated successfully, but these errors were encountered: