{# v2.3: Typed configuration form for one plugin's own [plugins.] section. The panel could only switch a plugin on and off, so a plugin's real settings - SMTP host, webhook URL, poll interval, threshold, cooldown - were reachable only by editing config.toml by hand. This form renders them from the schema the plugin declares next to its own `activate()`. Two rules this template exists to enforce: * Every field shows its EFFECTIVE value AND the source it came from (config.toml, .env, or the built-in default). A value without its source is what made the old page unreadable - the reader could not tell which of three files was actually in charge. * A secret field is write-only. Its value is never rendered, not even in an attribute: the field reports whether one is set, and a new value is written to .env through the same writer the CLI uses. The controls are HTMX-only on purpose: no data-action, therefore no new frontend strings, and the shell already adds X-CSRFToken to every htmx request, which is what makes these POSTs CSRF-protected like every other settings write. #}
{{ _('Configuration:') }} [plugins.{{ plugin_section }}] {{ _('%(count)s setting(s), %(changed)s differ from the default', count=field_count, changed=changed_count) }} {% if filter_name != 'all' %} {{ _('filtered') }} {% endif %} {# A close affordance, because a form the operator opened must be closable without saving. Nothing here needs a script file: the shell's htmx swaps innerHTML, so an inline handler on the element is what runs. #}
{% for n in notices %}
{{ n.text }}
{% endfor %} {% if errors.get('form') %}
{{ errors.get('form') }}
{% endif %} {% if not has_schema %}

{{ _('This plugin declares no schema in this build, so these controls were derived from the keys present in config.toml. Types inferred from a value can be wrong — check the effective value after saving.') }}

{% endif %} {% if not shown_count %}

{{ _('No setting is shown: every field is at its default and the readability filter is active.') }} {% if changed_count %} {{ _('%(count)s field(s) differ from the default.', count=changed_count) }}{% endif %}

{% endif %} {# The form is always rendered, even when the readability filter hides every field: a filter must never be a way to lose the ability to save, and the endpoint writes only the fields the form actually carried. #}
{% for f in fields %}
{{ f.key }} {{ _('changed from default') if f.differs_from_default else _('default') }} {{ _('effective from:') }} {{ f.source_label }}
{% if f.description %}
{{ f.description }}
{% endif %} {% if f.type == 'secret' %} {# Write-only: the stored value is never rendered, and the field reports only whether one exists. #}
{{ _('set') if f.secret_set else _('not set') }} {% if not f.writable %} {{ _('No .env variable is declared for this secret, so it cannot be changed from here.') }} {% else %} {% if f.env_var %}.env: {{ f.env_var }}{% endif %} {% endif %}
{% if f.secret_original %}
{{ _('A value is stored; it is never displayed.') }}
{% else %}
{{ _('No value is stored yet.') }}
{% endif %} {% elif f.type == 'toggle' %} {% elif f.type == 'number' %} {% elif f.type == 'select' %} {% elif f.type == 'list' %} {% else %} {% endif %}
{{ _('default:') }} {{ f.default_text }} {%- if f.differs_from_shipped %} · {{ _('differs from the shipped config.toml') }}{% endif %} {%- if not f.in_config %} · {{ _('not present in config.toml yet') }}{% endif %}
{% if f.unresolved_env %}
{{ _('No value is in effect: config.toml refers to ${%(var)s}, which .env does not define and which has no fallback.', var=f.unresolved_env) }}
{% endif %} {% if f.secret_in_config %}
{{ _('This is a literal value in config.toml, so a value saved to .env will not take effect until config.toml references the variable.') }}
{% endif %} {% if errors.get(f.key) %}
{{ errors.get(f.key) }}
{% endif %}
{% endfor %}
{{ _('Written to config.toml with a timestamped backup; secrets go to .env.') }} {{ config_path }}