Skip to content

design-settings: reset, export and import for Customizer-backed design - #27

Open
juliacanzani wants to merge 3 commits into
feature/onboardingfrom
feature/design-settings
Open

juliacanzani wants to merge 3 commits into
feature/onboardingfrom
feature/design-settings

Conversation

@juliacanzani

Copy link
Copy Markdown

A module for plugins whose design lives in the Customizer: Design Upgrade Pro for LearnDash, Design Upgrade Pro for H5P and Quiz Customizer. Each gets the same Design tab, and an export from one site carries the whole suite's design to another. See design-settings/readme.md.

API

design_settings\register( $plugin, [ 'options' => [...], 'theme_mods' => [...], 'panel' => '...', 'migrate' => fn($section, $from) => $section ] );
register_plugin_settings( $plugin, [ 'tabs' => [ 'design' => design_settings\tab( $plugin ), ... ] ] );

Behaviour

  • Export: one plugin or all registered, as tangible-design-settings v1 JSON. Only registered options and theme mods are included; licences never are. Empty sections export as {}.
  • Import: upload, then a review per plugin (applied/skipped counts, untick plugins), then apply.
    • Every value is matched to a registered Customizer setting and run through that setting's own sanitize()/validate(), so there's no second allowlist. Anything else is skipped and listed.
    • migrate sees the raw section first.
    • Apply replaces each chosen plugin's design rather than merging.
  • Reset: native <dialog>. The capability is edit_theme_options.
  • Forms: printed from admin_footer, because the tab sits inside the framework's settings <form>. Controls join them via the form attribute.
  • Running registration outside a Customizer request: the global $wp_customize is set while customize_register callbacks run (LearnDash's reads it), and a throwing callback is contained and reported in the review.
  • Version: bumped to 20261003 (node version.js).

Testing

  • PHPUnit: 12 new tests covering export scope (licences never exported), parse rejection, sanitizer pass-through and refusal, migration, the global during registration, a throwing callback, replace semantics, reset scope, and empty sections exporting as maps. The full suite passed (125 tests, 345 assertions) in the wordpress-develop test image, and in random order three times. One early full run showed 4 failures that I couldn't reproduce in four later runs.
  • Browser, with H5P and Quiz Customizer on a LearnDash site:
    • export one plugin and export all;
    • an import with a valid colour and radius, an injection attempt, an unknown key, a licence option and an absent plugin: exactly the two valid values were written, and the H5P sheet rebuilt;
    • cancel leaves options untouched;
    • reset clears the option;
    • no JS errors.

🤖 Generated with Claude Code

juliacanzani and others added 3 commits October 3, 2026 12:07
… design

A module for plugins whose design lives in the Customizer (Design Upgrade
Pro for LearnDash, Design Upgrade Pro for H5P, Quiz Customizer), so each
gets the same Design tab and an export from one site carries the whole
suite's design to another.

- register( $plugin, [ options, theme_mods, panel, migrate ] ) and
  tab( $plugin ) for register_plugin_settings
- export: one plugin or all registered, as tangible-design-settings JSON;
  only registered options/theme mods, never licences
- import: upload, review per plugin (applied/skipped, untick), apply.
  Values are matched to registered Customizer settings and run through
  their own sanitize/validate; anything else is skipped and listed.
  A migrate callback sees the raw section first. Apply replaces, not
  merges.
- reset behind a native <dialog>; capability edit_theme_options
- forms print from admin_footer (the tab sits inside the framework's own
  settings form) and controls join them with the form attribute
- PHPUnit: export scope, parse, sanitizer pass-through and refusal,
  migration, replace semantics, reset scope

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…would

The review step builds a WP_Customize_Manager outside a Customizer
request, and LearnDash's customize_register callback reads the global
$wp_customize: get_panel() on null, a fatal on the settings page. Set
the global while callbacks run and restore it after; contain a callback
that throws, so a broken neighbour can't take the page down. Settings
it would have added are absent, so their values are skipped, never
written unsanitized, and the review shows a warning with the reason.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…p their keys

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant