Skip to content

Global Styles: kebab-case preset slugs when converting references to custom properties - #12656

Open
jorgefilipecosta wants to merge 3 commits into
WordPress:trunkfrom
jorgefilipecosta:fix/theme-json-kebab-case-preset-reference-slugs
Open

Global Styles: kebab-case preset slugs when converting references to custom properties#12656
jorgefilipecosta wants to merge 3 commits into
WordPress:trunkfrom
jorgefilipecosta:fix/theme-json-kebab-case-preset-reference-slugs

Conversation

@jorgefilipecosta

@jorgefilipecosta jorgefilipecosta commented Jul 23, 2026

Copy link
Copy Markdown
Member

Backport of WordPress/gutenberg#80583 — syncs WP_Theme_JSON::convert_custom_properties().

What

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 generated custom property kebab-cases the slug (--wp--preset--font-family--n-27, see get_settings_values_by_slug()), but convert_custom_properties() converted var:preset|font-family|n27 references verbatim to var(--wp--preset--font-family--n27), which references a custom property that does not exist. The mismatch affects every preset type referenced this way: colors, gradients, font sizes, font families, spacing, shadows.

convert_custom_properties() now kebab-cases the slug segment of exact three-segment var:preset|<type>|<slug> references using the same _wp_to_kebab_case() as the custom property generation, so both sides always agree. Any other var: value converts byte-identically to before.

References that render correctly today are unchanged: a reference only works today when its raw slug already equals the kebab-cased declaration name, and _wp_to_kebab_case() is the identity on exactly those slugs.

Testing

  • vendor/bin/phpunit tests/phpunit/tests/theme/wpThemeJson.php — 234 tests pass. The new test_get_stylesheet_kebab_cases_preset_reference_slugs fails without the class-wp-theme-json.php change and covers font family, spacing, and duotone references.
  • Manual: register a font family with slug n27 in a theme's theme.json, assign it in Site Editor → Styles → Typography, save, and view the front end: the computed font-family now references the generated --wp--preset--font-family--n-27 custom property and the font applies.

Trac ticket: TBD

Use of AI Tools

AI assistance: Yes
Used for: drafting the fix, tests, and this description; reviewed and edited by me.


This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.

Copilot AI review requested due to automatic review settings July 23, 2026 09:58
@github-actions

Copy link
Copy Markdown

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 props-bot label.

Core Committers: Use this line as a base for the props when committing in SVN:

Props jorgefilipecosta.

To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook.

@jorgefilipecosta
jorgefilipecosta force-pushed the fix/theme-json-kebab-case-preset-reference-slugs branch from c67ec4b to 5915e9a Compare July 23, 2026 10:03

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR backports a Gutenberg fix to WordPress core to ensure Global Styles preset references are converted to CSS custom properties using the same kebab-cased slug transformation as the generated preset variables, preventing mismatches that cause styles not to apply on the front end.

Changes:

  • Update WP_Theme_JSON::convert_custom_properties() to kebab-case the slug segment for exact var:preset|<type>|<slug> references (excluding duotone) so references align with generated preset custom property names.
  • Add a PHPUnit test that verifies preset references (font-family, spacing) resolve to kebab-cased custom property names and that duotone references remain unchanged.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
tests/phpunit/tests/theme/wpThemeJson.php Adds coverage ensuring preset reference slugs are converted to kebab-case in the stylesheet output (with duotone preserved).
src/wp-includes/class-wp-theme-json.php Aligns preset reference conversion with preset custom property generation by kebab-casing the referenced slug for three-part preset references.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copilot AI review requested due to automatic review settings July 23, 2026 10:03
@github-actions

Copy link
Copy Markdown

Test using WordPress Playground

The changes in this pull request can previewed and tested using a WordPress Playground instance.

WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser.

Some things to be aware of

  • All changes will be lost when closing a tab with a Playground instance.
  • All changes will be lost when refreshing the page.
  • A fresh instance is created each time the link below is clicked.
  • Every time this pull request is updated, a new ZIP file containing all changes is created. If changes are not reflected in the Playground instance,
    it's possible that the most recent build failed, or has not completed. Check the list of workflow runs to be sure.

For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation.

Test this pull request with WordPress Playground.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

tests/phpunit/tests/theme/wpThemeJson.php:1066

  • This assertion expects duotone preset references to keep the raw slug (blueOrange2). However, duotone preset IDs are built from kebab-cased slugs in WP_Duotone (e.g. blueOrange2 becomes blue-orange-2), so the reference needs to use the kebab-cased slug to be resolvable as a preset.
		// Duotone references keep the raw slug.
		$this->assertStringContainsString(
			'var(--wp--preset--duotone--blueOrange2)',
			$stylesheet
		);

Comment thread src/wp-includes/class-wp-theme-json.php Outdated
Comment thread tests/phpunit/tests/theme/wpThemeJson.php Outdated
Copilot AI review requested due to automatic review settings July 23, 2026 10:44
@jorgefilipecosta
jorgefilipecosta force-pushed the fix/theme-json-kebab-case-preset-reference-slugs branch from 5915e9a to 9da9747 Compare July 23, 2026 10:44

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

Comment thread src/wp-includes/class-wp-theme-json.php
Comment thread src/wp-includes/class-wp-theme-json.php

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (2)

src/wp-includes/class-wp-theme-json.php:5576

  • convert_custom_properties() kebab-cases the slug for all var:preset|…|… references, including var:preset|duotone|<slug>. Duotone custom properties are generated by WP_Duotone using the raw slug (see WP_Duotone::get_css_custom_property_name()), so kebab-casing here can produce var(--wp--preset--duotone--…) references that don’t exist for slugs that change under _wp_to_kebab_case().
			if ( 3 === count( $parts ) && 'preset' === $parts[0] ) {
				$parts[2] = _wp_to_kebab_case( $parts[2] );
			}

src/wp-includes/class-wp-theme-json.php:5552

  • The new @since 7.2.0 note says preset reference slugs are kebab-cased to match generated custom properties, but duotone custom properties intentionally use the raw slug. The docblock should reflect the duotone exception to avoid misleading API docs.
	 * @since 7.2.0 Preset reference slugs are kebab-cased to match the generated custom properties.

Comment thread tests/phpunit/tests/theme/wpThemeJson.php

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

src/wp-includes/class-wp-theme-json.php:5552

  • The new docblock line uses @since 7.2.0, but this branch is currently on 7.1 (see other recent @since 7.1.0 entries throughout this file). The @since tag should reflect the first WordPress version that includes this behavior change, so it likely needs to be 7.1.0 instead of a future version.
	 * @since 6.3.0
	 * @since 7.2.0 Preset reference slugs are kebab-cased to match the generated custom properties.

@jorgefilipecosta
jorgefilipecosta force-pushed the fix/theme-json-kebab-case-preset-reference-slugs branch from 0a396d1 to 40d60c1 Compare August 31, 2026 13:31
@github-actions

Copy link
Copy Markdown

Trac Ticket Missing

This pull request is missing a link to a Trac ticket. For a contribution to be considered, there must be a corresponding ticket in Trac.

To attach a pull request to a Trac ticket, please include the ticket's full URL in your pull request description. More information about contributing to WordPress on GitHub can be found in the Core Handbook.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants