- pact: AdminClientAssets, AdminAction, AdminActionInput, AdminActionResult,
HasAdminActions and AdminPartialData contracts
- fields.yaml type: widget with widget, action and fill keys; boot checks the
plugin tag prefix, the registered action and writable scalar fill fields
- POST .../widgets/{field} behind requireAjax, controller and action
permissions, scoped non-locking record read and a server-side fill filter
- typed OpenAPI operation, inventories and an acme conformance case
6.9 KiB
pact
Capability interfaces that compiled plugins implement to contribute routes, config, migrations, middleware, commands, admin screens, translations, mail templates and jobs.
import "git.golem15.com/golem15/summercms/modules/pact"
Overview
pact is the contract layer between plugins and the framework. It holds interfaces and plain data types, with no behaviour of its own. A plugin opts into a capability by implementing one of the Has* interfaces, and the framework package that owns the capability discovers it with a type assertion (party for config, surf for routes and middleware, lagoon for migrations, cabana for admin controllers). It replaces the register*() methods of a WinterCMS PluginBase (registerPermissions, registerNavigation, registerSettings and so on) with small, separately implementable interfaces.
Features
- Plugin capability interfaces:
pact.HasRoutes,pact.HasConfig,pact.HasMigrations,pact.HasCommands,pact.HasModels,pact.HasJobs,pact.HasLang,pact.HasLangOverridesandpact.HasMailTemplates. - HTTP contracts: the
pact.Routergroup builder (implemented by surf), thepact.Middlewaretype, and named, parameterized (name:param) and house-envelope middleware throughpact.HasMiddleware,pact.HasMiddlewareFactoriesandpact.HasHouseMiddleware. - Backend registration data:
pact.Permission,pact.NavigationItemandpact.SettingsItem, exposed throughpact.HasPermissions,pact.HasNavigationandpact.HasSettings. - Admin controller contracts:
pact.AdminController,pact.HasAdminControllers,pact.AdminAssets(embedded Winter-shaped admin YAML),pact.AdminPermissionedandpact.AdminRecordSource. - Admin extension contracts, so a plugin extends the compiled admin SPA without a Node build:
pact.AdminClientAssets(per-controller JS and CSS from the plugin's embeddedassets/tree, Winter'saddJs/addCss),pact.HasAdminActionswithpact.AdminAction,pact.AdminActionInputandpact.AdminActionResult(named toolbar and widget actions whose routes, CSRF check, permissions and record scoping the framework owns), andpact.AdminPartialData(the curated view model a partial template renders). - Optional admin hooks a controller or model can implement: list and form query scoping (
pact.ListExtendQuery,pact.FormExtendQuery), create, update and delete hooks (pact.FormBeforeCreate,pact.FormAfterUpdate,pact.FormBeforeDeleteand their siblings), relation hooks (pact.RelationExtendManageQuery,pact.RelationExtendOptionsQuery,pact.RelationBeforeLink), filter scopes (pact.FilterScope,pact.FilterOptions) and dropdown options (pact.DropdownOptionsProvider). - A background job contract (
pact.Job,pact.JobArgs) that does not depend on any queue library. pact.OptionalMessage, a service an optional plugin can publish so others integrate with it without importing its package.pact.HasModels,pact.HasJobsandpact.OptionalMessageare declared for plugins to implement, but no framework package consumes them yet.
Usage
A plugin declares its capabilities by implementing the interfaces and asserting them at compile time:
package blog
import (
"net/http"
"git.golem15.com/golem15/summercms/modules/pact"
)
var (
_ pact.HasRoutes = (*Plugin)(nil)
_ pact.HasPermissions = (*Plugin)(nil)
)
type Plugin struct{}
func (p *Plugin) Routes(r pact.Router) error {
r.Group("/api/blog", []string{"auth"}, func(r pact.Router) {
r.Get("/posts", listPosts)
r.Get("/posts/{id}", showPost)
r.Where("id", "[0-9]+")
})
return nil
}
func (p *Plugin) Permissions() []pact.Permission {
return []pact.Permission{
{Code: "acme.blog.access_posts", Tab: "Blog", Label: "Manage posts"},
}
}
func listPosts(w http.ResponseWriter, r *http.Request) {}
func showPost(w http.ResponseWriter, r *http.Request) {}
API reference
| Identifier | Description |
|---|---|
pact.Router |
Laravel-style route group builder (pact.Router.Group, pact.Router.GroupRaw, one method per HTTP verb, pact.Router.Where, pact.Router.WhereIn); implemented by surf. |
pact.HasRoutes |
Declares HTTP routes on a pact.Router. |
pact.Middleware |
A named func(http.Handler) http.Handler wrapper. |
pact.HasMiddleware |
Registers named middleware. |
pact.HasMiddlewareFactories |
Registers parameterized middleware resolved from name:param at wrap time. |
pact.HasHouseMiddleware |
Registers middleware tagged as envelope and error handling, which raw groups refuse. |
pact.HasConfig |
Ships default YAML config, merged under the plugin ID. |
pact.HasMigrations |
Ships an ordered gormigrate set, run with a per-plugin history table. |
pact.HasCommands |
Contributes bonfire console commands to the application binary. |
pact.HasModels |
Exposes GORM models. |
pact.Job |
Background unit of work that receives pact.JobArgs. |
pact.HasJobs |
Registers background jobs. |
pact.HasLang |
Ships translation YAML under lang/<locale>/<group>.yaml. |
pact.HasLangOverrides |
Replaces or adds translations of any loaded namespace, including the framework's own. |
pact.HasMailTemplates |
Ships mail templates and layout aliases. |
pact.Permission |
One backend permission entry (code, tab, label, roles). |
pact.NavigationItem |
One backend navigation entry, with an optional side menu. |
pact.SettingsItem |
One settings screen entry. |
pact.AdminController |
Admin controller identity: ID, model name and YAML config directory. |
pact.AdminAssets |
Embedded tree of the plugin's admin YAML. |
pact.AdminRecordSource |
Supplies a new model record for the generic admin handlers. |
pact.AdminClientAssets |
Declares a controller's admin JS (AdminJS) and CSS (AdminCSS) files, paths under the plugin's assets/ directory. |
pact.AdminAction |
One named controller action: name, label, extra permissions and the Go Run function. |
pact.AdminActionInput |
What an action receives: widget field, optional record id and scoped record, and the fill snapshot. |
pact.AdminActionResult |
What an action returns: a message for the toast and the fill write-back values. |
pact.HasAdminActions |
Registers a controller's actions for toolbar.buttons and type: widget fields. |
pact.AdminPartialData |
Supplies the view model a controller partial template renders; never the GORM model. |
pact.FilterScope |
Model scopes a list filter may call, limited to an exact allow list. |
pact.Option |
One dropdown choice (value and label). |
Dependencies
- SummerCMS modules: bonfire (the command type in
pact.HasCommands). - Third-party:
github.com/go-gormigrate/gormigrate/v2,gorm.io/gorm. - Standard library:
context,io/fs,net/http.
Testing
go test ./modules/pact/...
The tests are compile-time interface checks and need no external services.