-
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
Document experimental theme.json #22518
Changes from 2 commits
9bd1ca1
1579467
88dd566
d0bcf65
7f82de8
13dcd7e
e962978
3815514
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,219 @@ | ||
# Themes & Block Editor | ||
|
||
This is intended to document the current direction and work in progress about how themes can hook into the various sub-systems that the Block Editor provides. | ||
|
||
* Rationale | ||
* Specification | ||
* Current Status | ||
|
||
## Rationale | ||
|
||
The Block Editor surface API has evolved at different velocities, and it's now at a point where is showing some growing pains, specially in areas that affect themes. Examples of this are: the ability to [control the editor programmatically](https://make.wordpress.org/core/2020/01/23/controlling-the-block-editor/), or [a block style system](https://github.com/WordPress/gutenberg/issues/9534) that facilitates user, theme, and core style preferences. | ||
|
||
This describes the current efforts to consolidate the various APIs into a single point: a `experimental-theme.json` file. | ||
|
||
When this file is present and the Full Site Editing experiment is enabled, a few Block Editor mechanisms that are activated. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we really need to limit the theme.json to FSE? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok, so there are two things here:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes, that was my thinking, I see value for this for regular themes too.
Definitely, especially "post". What's the reasoning for loading this in the site editor page only? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Draft PR to open this up #22520
Just being extra-cautious about which contexts had this loaded. With the current direction (enable features, etc), it makes more sense to open it up. |
||
|
||
### Presets become CSS Custom Properties | ||
|
||
Presets such as [color palettes](https://developer.wordpress.org/block-editor/developers/themes/theme-support/#block-color-palettes), [font sizes](https://developer.wordpress.org/block-editor/developers/themes/theme-support/#block-font-sizes), and [gradients](https://developer.wordpress.org/block-editor/developers/themes/theme-support/#block-gradient-presets) will be enqueued as CSS Custom Properties for themes to use. | ||
|
||
These are enqueued for both in the front-end and the site editor. | ||
|
||
### Some block styles are managed | ||
|
||
By providing the block style properties in a structured way, the Block Editor can "manage" the CSS that comes from different origins (user, theme, and core CSS), reducing the amount of CSS loaded in the page and preventing specificity wars due to the competing needs of the components involved (themes, blocks, plugins). | ||
|
||
### Individual features can be controlled per block | ||
|
||
The Block Editor already allows the control of specific features such as alignment, drop cap, whether it's present in the inserter, etc. The goal is that these are also available for themes to control. | ||
|
||
## Specification | ||
|
||
The specification for the `experimental-theme.json` follows the three main functions described in the section above: presets, styles, and features. | ||
|
||
``` | ||
{ | ||
presets: { | ||
color: [ ... ], | ||
font-size: [ ... ], | ||
gradient: [ ... ], | ||
}, | ||
styles: { ... }, | ||
features: { ... } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I still have a small concern about the "presets" and "features". For instance to disable colors entirely you'd have to do:
So two separate locations to "control" the editor. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I agree, that'd be not ideal. This is not implemented yet but the way I imagine this could work is by compressing it to:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it's still two different top level keys to disable a feature though. it's not the value itself that bothers me. |
||
} | ||
``` | ||
|
||
The file is divided into sections that represent different contexts: individual blocks, as well as the global environment. | ||
|
||
``` | ||
{ | ||
global: { | ||
presets: { ... }, | ||
styles: { ... }, | ||
features: { ... } | ||
}, | ||
core/paragraph: { | ||
presets: { ... }, | ||
styles: { ... }, | ||
features: { ... } | ||
}, | ||
core/group: { | ||
presets: { ... }, | ||
styles: { ... }, | ||
features: { ... } | ||
} | ||
} | ||
``` | ||
|
||
Some of the functions are context-dependant. Take, as an example, the drop cap: | ||
|
||
``` | ||
{ | ||
global: { | ||
features: { | ||
dropCap: false | ||
} | ||
}, | ||
core/paragraph: { | ||
features: { | ||
dropCap: true, | ||
} | ||
}, | ||
core/image: { | ||
features: { | ||
dropCap: true | ||
} | ||
} | ||
} | ||
``` | ||
|
||
In the example above, we aim to encapsulate that the drop cap should be disabled globally but enabled in the paragraph context. The drop cap in the image context wouldn't make sense so should be ignored. | ||
|
||
## Current Status | ||
|
||
### Presets | ||
|
||
This function is only enabled for the global section. | ||
|
||
The generated CSS Custom Properties follow this naming schema: `--wp--preset--{preset-category}--{preset-slug}`. | ||
|
||
For this input: | ||
|
||
``` | ||
presets: { | ||
color: [ | ||
{ | ||
slug: 'strong-magenta', | ||
value: #a156b4, | ||
}, | ||
{ | ||
slug: 'very-dark-grey', | ||
value: #444, | ||
} | ||
], | ||
} | ||
``` | ||
|
||
The following stylesheet will be enqueued to the front-end and site editor: | ||
|
||
```css | ||
:root { | ||
--wp--preset--color--strong-magenta: #a156b4; | ||
--wp--preset--color--very-dark-gray: #444; | ||
} | ||
``` | ||
|
||
The goal is that presets can be defined using this format, although so far the name property (used to be shown in the editor) can't be translated from this file. For that reason, and to maintain backward compatibility, the presets declared via `add_theme_support` will also generate the CSS Custom Properties. The equivalent example to above is: | ||
|
||
```php | ||
add_theme_support( 'editor-color-palette', array( | ||
array( | ||
'name' => __( 'strong magenta', 'themeLangDomain' ), | ||
'slug' => 'strong-magenta', | ||
'color' => '#a156b4', | ||
), | ||
array( | ||
'name' => __( 'very dark gray', 'themeLangDomain' ), | ||
'slug' => 'very-dark-gray', | ||
'color' => '#444', | ||
), | ||
) ); | ||
``` | ||
|
||
If the `experimental-theme.json` contains any presets, these will take precedence over the ones declared via `add_theme_support`. | ||
|
||
### Styles | ||
|
||
Each block will declare which style properties it exposes. This has been coined as "implicit style attributes" of the block. These properties are then used to automatically generate the UI controls for the block in the editor, as well as being available through the `experimental-theme.json` file for themes to target. | ||
|
||
The list of properties that are currently exposed via this method are: | ||
|
||
- Paragraph and Heading: line-height, font-size, color. | ||
- Group, Columns, and MediaText: color. | ||
|
||
### Features | ||
|
||
This is being implemented, so it's not currently available. | ||
|
||
### Recap of current available functions | ||
|
||
``` | ||
{ | ||
global: { | ||
presets: { | ||
color: [ | ||
{ | ||
slug: <preset slug>, | ||
value: <preset value>, | ||
}, | ||
{ ... }, | ||
], | ||
font-size: [ | ||
{ | ||
slug: <preset slug>, | ||
value: <preset value>, | ||
}, | ||
{ ... }, | ||
], | ||
gradient: [ | ||
{ | ||
slug: <preset slug>, | ||
value: <preset value>, | ||
}, | ||
{ ... }, | ||
] | ||
} | ||
}, | ||
core/paragraph: { | ||
styles: { | ||
line-height: <value>, | ||
font-size: <value>, | ||
color: <value>, | ||
} | ||
}, | ||
/* core/heading/h1, core/heading/h2, etc */ | ||
core/heading/h*: { | ||
Comment on lines
+199
to
+200
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems to be exceptional behaviour in that it breaks the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agreed, this is something that needs untangling. I see a few things here. They are related, although can be separate discussions as well. Here's the current direction and some thoughts about it:
The heading block represents 6 HTML elements (h1-h6). That variation is captured as a block attribute, levels. I don't know any other block that does the same, although I can see potential for more cases. For example, a block that wanted to use There's another aspect here that I'm unsure how/whether plays with this: block variations. As far as I've seen, the block variations in use don't represent structural changes, but, they could if the block author uses them for that.
How any block register its selector is not documented. An old iteration of the managed CSS PR proposed using a new key This is how the proposal looked like for the paragraph block:
The global styles mechanism knew how to match both pieces of data, the theme.json block name to the block.json selector. This is fine for most blocks, but then we face blocks that represent multiple HTML elements, such as heading. This is what I proposed at the time:
Essentially, each block.json selector key creates a new block name in
The current proposal is:
However, we could do differently. Some alternatives that I've considered are:
The current proposal seemed clearer to me, both from the human and computer perspective. Does this create any new thoughts/heps to advance the conversation? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
It's not exposed through any visual option yet, but the Group block has an attribute for changing which tag it uses. (So you could use it for I think it's worth noting that, at least at some point (I don't know if it's still the case), it was thought that the block editor could be used in contexts where the output isn't HTML. I wonder if maybe some of the proposed ideas may be too HTML-specific. I suppose heavy reliance on HTML also causes problems for the mobile app. As for the Heading block, I really don't think it makes sense to target h1-h6 elements through it. h1-h6 elements can and often will occur outside of Heading blocks. Theme authors ought to target h1-h6 elements as they normally would. It's worth noting that there are variations in how blocks should be styled that depend, not on style variations, but an attribute that toggles whether a certain CSS class is added or not. The Latest Posts block has a grid and a list mode. The two should be styled very differently. But you can't use target either using style variations, because they aren't style variations. But the two modes also don't use different markup, if I recall correctly. The only difference is what CSS classes are applied. But for a CSS class that is unique to a particular block, I don't think we should be targeting that class name in I'm not sure exactly how/if this would work/look in practice. Just an idea I thought I'd share. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the group nudge, Zebulan. It led me to find another block that represents multiple HTML elements: the list block can use For most blocks we have more specific selectors through the named class As for not optimizing for HTML: I'd say that expressing the block attributes as a pair of property/value that is decoupled from the output (CSS) runs with that idea and may be helpful for other environments as well. Granted, right now, there's still a coupling between the block style attributes and CSS properties --- it doesn't need to be this way, though. I'd put the latest post example in the same category of style variations. It seems the direction we're going towards is that style variations should be different sets of values for block style attributes (and not classes). Implementation-wise, we're far from that idea, but I have it in my background as something to explore. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. After some PRs that have landed, I was able to put together #22698 which takes the block data (block selectors + block implicit attributes) from the block registry instead of being hardcoded. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As I mentioned above, I've looked at the intersection of block variations and block selectors at #22805 (comment) TLDR: those two things seem to be independent. |
||
styles: { | ||
line-height: <value>, | ||
font-size: <value>, | ||
color: <value>, | ||
} | ||
}, | ||
core/columns: { | ||
styles: { | ||
color: <value>, | ||
} | ||
}, | ||
core/group: { | ||
styles: { | ||
color: <value>, | ||
} | ||
}, | ||
core/media-text: { | ||
styles: { | ||
color: <value>, | ||
} | ||
}, | ||
} | ||
``` |
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.
Actually, we should add a sentence here to clarify the experimental state of the APIs and that they're subject to change at any moment (like the block-based theme doc)
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.
How about 7f82de8 ? Mostly copied verbatim from the block-themes page.
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.
Great but I have the same question as https://github.com/WordPress/gutenberg/pull/22518/files#r428571002
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.
Is that the link you intended to share? It points to this same thread so I'm not sure I follow.
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, it's the comment bout the FSE requirement :)