- placement: tabs before/after tab anchors, anchor cursor for plugin
order, own-field anchors sorted with cycle detection, Requires() rule,
anchor tab inheritance, Hide with reference checks, zone refusal (D-101)
- boot errors name plugin, controller and offending name; fileupload is
refused (D-100); localized tab label collisions checked in Activate
- extension widgets dispatch to AdminFormExtension.Actions, partials
render from the contributor's Dir through PartialData, plugin field
types decode for Save and load after Load, translatable values reach
Save as locale maps and never the owner's translations
- Permissions and Visible apply to schema, show, save, widgets and
partials; AdminFormErrors answer 422, Save notices join meta.notices
refusedViewModel compared only the top-level type with the controller's
model. It now walks the type through pointers, slices, arrays, maps,
struct fields and the results of exported methods, and the values held
in interface-typed members, refusing the controller's model, any other
GORM model (TableName, a gorm tag, gorm.Model, gorm.DeletedAt) and
html/template's trusted content types anywhere in that structure.
- fields.yaml type: partial with a bare path name and config_list.yaml
headerPartial resolve to {ConfigDir}/_{name}.htm, parsed at boot; the
controller must implement pact.AdminPartialData
- html/template render against a curated view model, then x/net/html
ParseFragment and a tag, attribute and URL allowlist with 64 KiB, 2000-node
and depth-32 caps; the model type and trusted template types are refused
- GET .../partials/{name} with optional ?id= loaded through the form scope
- golang.org/x/net becomes a direct requirement (D-18), no new module