fix(web): plugin settings form shows schema defaults for unsaved keys (#597)

The server-rendered plugin settings partial rendered straight from the
saved config, so an option added in a plugin update (geochron 1.2.0's
show_date / show_date_line, default true) drew as an unchecked box, and
the save route's missing-checkbox handling then stored it as false.
Enum dropdowns likewise showed their first option instead of the default.

- _load_plugin_config_partial runs the stored section through
  prepare_plugin_config (as GET /plugins/config does) before masking
  secrets, so a secret's schema default is masked too.
- render_field falls back to the field's own default, covering children
  of objects that declare a default of their own (where the defaults
  extraction stops).
- The legacy-boolean parity test now compares against the config the
  plugin actually runs with (defaults included).

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Chuck
2026-09-18 11:09:25 -04:00
committed by GitHub
co-authored by Claude Opus 5
parent 92f1960d00
commit 19686ab761
5 changed files with 244 additions and 8 deletions
@@ -29,6 +29,11 @@
{% macro render_field(key, prop, value, prefix='', plugin_id='') %}
{% if not prop_is_hidden(prop)|trim %}
{# A key the saved config doesn't have renders its schema default. The
route merges defaults first, but that merge stops at an object that
declares its own default (often {}), leaving its children missing here.
Booleans matter most: an unchecked box saves as false. #}
{% if value is none and prop.default is defined %}{% set value = prop.default %}{% endif %}
{% set full_key = (prefix ~ '.' ~ key) if prefix else key %}
{% set field_id = (plugin_id ~ '-' ~ full_key)|replace('.', '-')|replace('_', '-') %}
{% set label = prop.title if prop.title else key|replace('_', ' ')|title %}