Skip to content

Palette: auto-fill slug from Name with transliteration support #846

Open

Description

@bph

Follow-up to #838.

Why

Adding a palette entry in the Edit Theme Settings modal currently requires the user to type both the human-readable Name and a separate slug. The slug must be lowercase alphanumeric + dashes/underscores (server-side sanitize_key()), so users either type it twice or hit save-time errors. Worth auto-deriving slug from name as the user types.

Behavior

  • On a new palette row, typing in the Name field auto-fills the Slug field with the slugified name.
  • Auto-sync stops the moment the user manually edits the Slug field (per-row sticky flag).
  • Existing rows (loaded from theme.json) do not auto-sync — changing a saved slug is breaking, since CSS variables reference it (--wp--preset--color--<slug>).
  • If slugification produces an empty string (e.g. a name composed entirely of non-Latin characters), the slug field stays empty and the existing server-side validation surfaces the issue at Update time.

Transliteration

cleanForSlug from @wordpress/url is the JS equivalent of PHP's sanitize_title(). It quietly strips characters it can't normalize:

Input cleanForSlug Desired (per #812)
Grün gr-n gruen
Über rot ber-rot ueber-rot
Straße strae strasse
Café cafe cafe ✓
色 `` (empty) n/a (manual entry required)

#812 (reported by @hagege) calls this out as a bug in the existing "Save Changes to Theme" flow — the same transliteration concern applies to both flows.

Mappings the issue asks for:

  • ä → ae, Ä → Ae
  • ö → oe, Ö → Oe
  • ü → ue, Ü → Ue
  • ß → ss

Other languages with common transliterations (Nordic, Polish, Turkish, etc.) likely deserve coverage too. A general-purpose library (unidecode, transliteration) handles a wide range at the cost of bundle size; a curated map of European-language characters keeps the bundle small but misses long tail. Worth a design discussion in this issue before implementation.

Scope

Implementation should:

  1. Live in a shared util (src/utils/slugify.js or similar) so both the new Edit Theme Settings modal and the existing Save Changes to Theme flow (Issue with (german) umlaut #812) can use the same logic.
  2. Apply the German-umlaut transliterations from Issue with (german) umlaut #812 at minimum.
  3. Decide on coverage for other Latin-script diacritics (Nordic, Polish, Romance languages).
  4. Be debounced lightly to avoid jitter while typing.

References

Activity

  1. jasalt commented on Oct 14, 2026

    @jasalt

    Finding solution to this would be great.

    On most parts this suggestion sounds good but I think this would need to be resolved server-side as JavaScript solution would not cover CLI usage that #830 would add or REST request context. JavaScript-side result might be used as suggestive, but server-side validation would be authoritative.

    The PHP exporter already has its own slug-generation path. CBT_Theme_Patterns::pattern_from_wp_block() calls sanitize_title_with_dashes( $pattern_post->post_title ). A shared JavaScript helper will not affect that path unless the PHP code is changed too.

    I've ran into this (#812) messing with Nordic letters with my own wp create-block-theme save CLI command https://github.com/jasalt/wpcli-create-block-theme.

  2. jasalt commented on Oct 14, 2026

    @jasalt

    WordPress PHP function remove_accents() could be useful for German, Nordics and others, but it would be not sufficient for arbitrary Unicode like Chinese characters and emojis that it leaves intact, and the subsequent sanitize_title_with_dashes() would make them percent encoded.

  3. jasalt commented on Oct 14, 2026

    @jasalt

    Additionally transliteration would need collision checks. Café and Cafe, for example, can become the same slug. Validation should cover the whole batch before files are written or source patterns are deleted.

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions