pact.SettingsItem.Controller: a settings entry that links to an admin controller
cabana link compile/validation, metadata filtering (Allows + canOpen), singleton-endpoint 404s
SPA settingsPath / settingsLinkFor; Settings-aware rail, breadcrumbs and page title
translate plugin: Locales on the Settings page instead of the main navigation
sm-grzybyfunkcjonalne-app
sm-summercmsio-app
added
patterns
Settings entries share one code namespace across singleton and link entries
Registry.Setting hides link entries so protectSetting answers 404 with no http.go change
created
modified
deleted
modules/cabana/settings_link_test.go
modules/cabana/example_settings_test.go
../sm-translate-plugin/admin_settings.go
admin/src/components/form/fields/SwitchField.vue
modules/pact/capabilities.go
modules/cabana/settings.go
modules/cabana/registry.go
modules/cabana/navigation.go
modules/cabana/contracts.go
modules/cabana/example_test.go
admin/openapi/admin.json
admin/src/api/schema.d.ts
admin/tests/fixtures/settings.json
admin/src/state/useSettings.ts
admin/src/views/SettingsIndexView.vue
admin/src/components/shell/PluginRail.vue
admin/src/components/shell/Breadcrumbs.vue
admin/src/app/pageTitle.ts
modules/pact/README.md
modules/cabana/README.md
docs/backend/settings.md
docs/setup/coming-from-wintercms.md
modules/boardwalk/dist/
../sm-translate-plugin/admin.go
../sm-translate-plugin/plugin_test.go
../sm-translate-plugin/locales_admin_test.go
../sm-translate-plugin/README.md
../sm-translate-plugin/admin_navigation.go
A settings link entry rejects Model as well as Form/NewModel, so the SPA never sees a misleading model string
Translate's settings category follows the PHP reference (golem15.translate::lang.plugin.name); no core System category constant added
The docs Go example for the link entry lives in its own file (example_settings_test.go) because example_controller_test.go is embedded whole in admin-controllers.md
Quick 261007-p4y: Toggle proportions and Settings controller links Summary
The admin switch now has pixel-based proportions: a 44x26 track and a 20px knob. Settings entries can now link to an admin controller through an additive pact.SettingsItem.Controller field, covered from start-up validation through to the Settings page. The translate plugin now lists Locales on the Settings page, under the Translate category, as WinterCMS did.
feat(admin): open controller-link settings entries from the settings index
sm-translate-plugin (separate repo, 1 commit):
Task
Commit
Message
3
bde3f1a
feat(settings): open Locales from the Settings page
No commit has a co-author trailer. No commit touches .planning. Nothing was pushed.
What was built
Switch:w-[44px] and size-[20px] give 3 + 20 + 18 + 3 = 44, with a symmetric inset. Dist was rebuilt and committed on its own.
pact:SettingsItem.Controller is a new additive field placed before Form. Keyed literals in other code compile unchanged, and a grep of the meta repo found no unkeyed ones.
cabana:
compileSettingLink rejects a link that also sets Form, NewModel or Model.
The link branch in compileContributions skips the AdminFS requirement.
After every plugin is collected, start-up fails on an unknown controller with cabana: setting <code> references unknown controller <id>.
Registry.Setting hides link entries, so all three singleton endpoints answer 404.
SettingsEntry.Controller is serialised as json:"controller" and is always present.
Metadata lists a link entry only when the principal passes Allows(item.Permissions) and canOpen(controller).
OpenAPI:controller is a required string on cabana.SettingsEntry in admin.json and schema.d.ts. The settings fixture entries now carry "controller": "".
SPA:
Index cards link through settingsPath.
The rail marks Settings current on a linked controller that has no navigation entry. A linked controller that does have a navigation entry keeps its plugin highlighted.
Breadcrumbs on such a page read Ustawienia > <label> [> record].
The page title falls back to the entry label.
Translate:Plugin.Settings() returns the single locales link entry, with values taken from the PHP registerSettings reference. admin_navigation.go is removed, and HasNavigation is replaced by HasSettings in the assertion block.
TDD evidence
Go RED: settings_link_test.go failed to build (unknown field Controller in struct literal of type pact.SettingsItem). After the change it passes: 4 tests plus 9 subtests.
SPA RED: 6 new cases failed across useSettings, Settings, PluginRail, Breadcrumbs and pageTitle. After the change it passes: all 1083 tests in 74 files.
Translate RED: the build failed (p.Settings undefined). After the change it passes, and the harness test ran against Postgres via testcontainers.
Verification
summercms.go: go vet ./... and go test ./... -count=1 pass. So do scripts/check-admin-openapi.sh --check, scripts/check-admin-dist.sh, go test ./cmd/summer -run TestDocsTree, npm --prefix admin run typecheck and npm --prefix admin test.
sm-translate-plugin: gofmt -l . is clean, and go vet ./... and go test ./... -count=1 pass.
Both working trees are clean, apart from the orchestrator-owned .planning/quick/... directory.
Deviations from Plan
Auto-fixed Issues
1. [Rule 3 - Blocking] The docs snippet needed a src= reference and a shorter description
Found during: Task 2, commit A
Issue: TestDocsTree rejects a Go fence without src= and a frontmatter description over 160 characters. Adding the example to example_controller_test.go changed a whole-file snippet in docs/backend/admin-controllers.md.
Fix: I added modules/cabana/example_settings_test.go, which holds LinkedBlogPlugin and a docs:start settings-link region. TestDocsSettingsLink in example_test.go activates the plugin through cabana.Activate, which proves the link compiles end to end. The settings.md description is shortened.
2. [Process] The admin-behaviour paragraph moved to commit B
The settings.md paragraph about the rail and breadcrumbs went into the SPA commit (0b09acd) rather than commit A, so each commit's docs match its code.
3. [Test fixture choice] Rail, breadcrumb and title tests use acme.lang.locales
The plan suggested acme.demo.locales, but acme.demo is in the navigation fixture, which would make the plugin highlight win. These tests use a plugin that is absent from navigation, acme.lang.locales. The path tests in useSettings still use acme.demo.locales.
Follow-ups
Consuming apps (sm-grzybyfunkcjonalne-app, sm-summercmsio-app) must bump their translate submodule to bde3f1a or later. They also need a framework tag that includes pact.SettingsItem.Controller (4a9b089 or later). Neither bump is done here, because it was out of scope.
The PHP plugin also registers a messages settings link. There is no Messages admin controller in the Go port yet, so only locales is registered.
Known Stubs
None.
Threat Flags
None. All new surface is covered by the plan's threat register: T-01 has the metadata filter tests, T-02 the 404 tests, T-03 the compile validation tests, and T-04 the settingsPath fallback test.