Global Styles: kebab-case preset slugs when converting references to custom properties#80583
Open
jorgefilipecosta wants to merge 5 commits into
Open
Global Styles: kebab-case preset slugs when converting references to custom properties#80583jorgefilipecosta wants to merge 5 commits into
jorgefilipecosta wants to merge 5 commits into
Conversation
jorgefilipecosta
requested review from
ellatrix and
tellthemachines
as code owners
July 22, 2026 17:21
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
|
Size Change: +250 B (0%) Total Size: 7.75 MB 📦 View Changed
|
jorgefilipecosta
force-pushed
the
fix/global-styles-preset-slug-kebab-case
branch
from
July 22, 2026 17:33
9af04a6 to
a9bed26
Compare
jorgefilipecosta
force-pushed
the
fix/global-styles-preset-slug-kebab-case
branch
2 times, most recently
from
July 22, 2026 18:20
080b939 to
f56e5a2
Compare
jorgefilipecosta
force-pushed
the
fix/global-styles-preset-slug-kebab-case
branch
from
July 22, 2026 18:54
f56e5a2 to
8b57be5
Compare
jorgefilipecosta
force-pushed
the
fix/global-styles-preset-slug-kebab-case
branch
from
July 22, 2026 19:42
8b57be5 to
7660324
Compare
jorgefilipecosta
requested review from
aaronrobertshaw,
andrewserong,
oandregal and
talldan
July 23, 2026 09:44
…custom properties WP_Theme_JSON_Gutenberg kebab-cases preset slugs when generating the preset custom properties (get_settings_values_by_slug()), but convert_custom_properties() converts stored references (var:preset|font-family|n27) with a verbatim | to -- replacement. For a slug that changes when kebab-cased, the reference (--wp--preset--font-family--n27) never matches the generated custom property (--wp--preset--font-family--n-27), so the preset does not apply on the front end. Kebab-case the slug of preset references in convert_custom_properties() with the same _wp_to_kebab_case() used for the generated custom properties. References that render correctly today are unchanged: they only work when the slug is already a kebab-case fixed point, on which _wp_to_kebab_case() is the identity. Duotone references keep the raw slug: they are resolved by slug lookup in WP_Duotone, not through the generated custom properties.
jorgefilipecosta
force-pushed
the
fix/global-styles-preset-slug-kebab-case
branch
from
July 23, 2026 10:01
01a4620 to
2ef3b1c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What?
Fixes #53695.
When a preset slug changes under kebab-casing (e.g. a font family with slug
n27), styles referencing that preset from theme.json or Global Styles never apply on the front end. The same mismatch affects every preset type referenced this way: colors, gradients, font sizes, font families, spacing, shadows.This PR fixes it in the one place responsible: the PHP conversion of stored preset references to CSS custom properties.
Why?
PHP kebab-cases the slug in one place but not in the other:
When generating the preset custom properties, the slug is kebab-cased with
_wp_to_kebab_case()— seeget_settings_values_by_slug():When converting stored references (
var:preset|font-family|n27) tovar()usages,convert_custom_properties()performs a verbatim|→--string replacement with no kebab-casing:The declared name has
n-27, the reference asks forn27, so the browser finds no such custom property and the style falls back. For slugs that don't change under kebab-casing (vivid-red,x-large,40) the two paths coincidentally agree, which is why the bug only surfaces with slugs liken27.convert_custom_properties()is the odd one out among all the serializers: the PHP block supports / style engine (wp_typography_get_preset_inline_style_value(),WP_Style_Engine::get_slug_from_preset_value()) kebab-case — which is why block-level markup renders correctly — and so do the client-side style engine and global styles engine, which is why the editor canvas renders correctly. Only this Global Styles reference conversion disagrees.How?
convert_custom_properties()now kebab-cases the slug segment ofvar:preset|<type>|<slug>references with the same_wp_to_kebab_case()the custom property generation uses, so both sides always agree. Only exact three-segmentpresetreferences are touched; any othervar:value converts byte-identically to before.Backward compatibility
References that render correctly today are provably unchanged: a reference only works today when its raw slug already equals the kebab-cased declaration name (i.e. the slug is a kebab-case fixed point), and
_wp_to_kebab_case()is the identity on exactly those slugs. Since both sides use the same function, the change can only converge a reference toward its declaration — never move a matching one away.The behavioral deltas are limited to references that are currently dead:
As a side effect,
WP_Theme_JSON::resolve_variables()can now actually resolve these references (previously the constructed name didn't exist in the computed vars).The editor is unaffected: the conversion runs when a config is sanitized for rendering; the global styles REST controller returns raw stored user data, so the client keeps seeing the same
var:preset|…values it does today. Since references keep being stored with raw slugs (no data format change), nothing changes for existing content beyond the fixed rendering.Core sync PR: WordPress/wordpress-develop#12656.
Testing Instructions
theme.json, register a font family whose slug changes when kebab-cased, e.g.:{ "fontFamily": "N27, sans-serif", "name": "N27", "slug": "n27" }font-familynow referencesvar(--wp--preset--font-family--n-27), matching the generated custom property, and the font applies. Without this PR the reference is--wp--preset--font-family--n27and the font falls back. Note that with this fix, previously saved (broken) references heal without a re-save, since the fix is applied at render time.PHP tests:
npm run test:unit:php:base -- -- --filter WP_Theme_JSON_Gutenberg_Test(222 tests passing, including new coverage asserting the kebab-cased reference output for font family and spacing). The full PHP suite was compared against trunk: identical results (all pre-existing failures, none introduced).