Skip to content

REST endpoint + CBT_Theme_Settings_Save service #837

Closed

Description

@bph

Part of #836. Server-side foundation for the Edit Theme Settings feature. UI is unaffected by this PR — the prototype's Update button remains a no-op until PR 1 wires the resolver.

Scope

Add a REST endpoint and service that persist a partial-theme.json payload to the active theme's theme.json on disk. No JavaScript changes.

Files

  • includes/class-create-block-theme-api.php — register POST /create-block-theme/v1/theme-settings, add rest_save_theme_settings handler.
  • includes/create-theme/theme-settings-save.php — new CBT_Theme_Settings_Save service class with run( array $payload ).
  • includes/class-create-block-theme-loader.php — load the new service file.
  • tests/phpunit/tests/test-theme-settings-save.php — new PHPUnit suite.

Endpoint contract

  • Method: POST /create-block-theme/v1/theme-settings
  • Capability: edit_theme_options
  • Request body (JSON; only present keys are written; missing keys leave theme.json untouched):
{
  "settings": {
    "color": { "defaultPalette": false, "palette": [], "gradients": [], "duotone": [] },
    "spacing": { "spacingSizes": [], "units": ["px","rem"] },
    "typography": { "fontFamilies": [], "fontSizes": [] },
    "layout": {}
  },
  "templateParts": [],
  "customTemplates": [],
  "removedShadowDefaults": ["natural", "sharp"]
}
  • Response: { "status": "SUCCESS", "theme_json": <merged theme.json array> }. Errors return WP_Error.

Service responsibilities

  1. Validate payload shape (top-level allowlist; type checks for known sub-keys). Reject unknown top-level keys.
  2. Sanitize strings (slugs, names, CSS values via sanitize_text_field and dedicated helpers). Use wp_validate_boolean() for flags.
  3. Read current theme.json via CBT_Theme_JSON_Resolver::get_theme_file_contents().
  4. Deep-merge settings.* (replace at leaf); array-replace for customTemplates and templateParts. Create missing parent keys cleanly (e.g., theme without prior settings.color accepts a new palette).
  5. Reify removedShadowDefaults into settings.shadow.defaultPresets: false + kept core shadows re-registered as settings.shadow.shadow: [...].
  6. Write via CBT_Theme_JSON_Resolver::write_theme_file_contents().
  7. Return the merged theme.json.

Acceptance criteria

  • Endpoint registered, capability-gated, returns merged theme.json on success.
  • Partial payload (only settings.color.palette) leaves other keys untouched.
  • Empty palette array clears the palette (distinct from missing key).
  • Theme without prior settings.color accepts a new palette without errors.
  • removedShadowDefaults: ["natural"] produces a theme.json with settings.shadow.defaultPresets: false and the other 4 core shadows re-registered.
  • Shadow reification is idempotent — running the same payload twice produces the same theme.json.
  • Malformed payload returns WP_Error with a 400-class status.
  • PHPUnit covers each acceptance criterion.

Out of scope

References

Activity

  1. changed the title [-]Edit Theme Settings: REST endpoint + CBT_Theme_Settings_Save service[/-] [+]REST endpoint + CBT_Theme_Settings_Save service[/+] on May 6, 2026
  2. self-assigned this
    on May 6, 2026
  3. added a commit that references this issue on May 21, 2026
    87fe02c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions