Repository navigation
REST endpoint + CBT_Theme_Settings_Save service #837
Copy link
Copy link
Closed
Labels
Description
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— registerPOST /create-block-theme/v1/theme-settings, addrest_save_theme_settingshandler.includes/create-theme/theme-settings-save.php— newCBT_Theme_Settings_Saveservice class withrun( 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 returnWP_Error.
Service responsibilities
- Validate payload shape (top-level allowlist; type checks for known sub-keys). Reject unknown top-level keys.
- Sanitize strings (slugs, names, CSS values via
sanitize_text_fieldand dedicated helpers). Usewp_validate_boolean()for flags. - Read current theme.json via
CBT_Theme_JSON_Resolver::get_theme_file_contents(). - Deep-merge
settings.*(replace at leaf); array-replace forcustomTemplatesandtemplateParts. Create missing parent keys cleanly (e.g., theme without priorsettings.coloraccepts a new palette). - Reify
removedShadowDefaultsintosettings.shadow.defaultPresets: false+ kept core shadows re-registered assettings.shadow.shadow: [...]. - Write via
CBT_Theme_JSON_Resolver::write_theme_file_contents(). - 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.coloraccepts a new palette without errors. -
removedShadowDefaults: ["natural"]produces a theme.json withsettings.shadow.defaultPresets: falseand 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_Errorwith a 400-class status. - PHPUnit covers each acceptance criterion.
Out of scope
- JS resolver, modal state lifting, save UX (PR 1 — tracked separately).
- Wiping user customizations on save — explicitly not done in v1 (see decision in [Tracking] Edit Theme Settings: phased implementation #836).
- WP-CLI command (separate effort).
References
- Tracking issue: [Tracking] Edit Theme Settings: phased implementation #836
- Pattern mirrored:
CBT_Theme_Save::run()inincludes/create-theme/theme-save.php. - Writer used:
CBT_Theme_JSON_Resolver::write_theme_file_contents()inincludes/create-theme/resolver_additions.php.
Reactions are currently unavailable
Activity
[-]Edit Theme Settings: REST endpoint + CBT_Theme_Settings_Save service[/-][+]REST endpoint + CBT_Theme_Settings_Save service[/+]Add /theme-settings REST endpoint + CBT_Theme_Settings_Save service (W…