Files
Jakub Zych d6003cd84b feat(11.1-03): add the Coming from WinterCMS concept map with a verified plugin example
- docs/setup/coming-from-wintercms.md maps WinterCMS concepts to checked
  pkg.Ident spans and lists what SummerCMS does not provide
- party BlogPlugin and ExamplePlugin, shown through src= fences
- TestDocsRequiredPages asserts required pages build as .html and .md
- index links the new page
2026-09-30 22:06:45 +02:00
..

party

Compiled plugin registry that orders plugins by their dependencies and runs their Register and Boot lifecycle.

import "git.golem15.com/golem15/summercms/modules/party"

Overview

party is the WinterCMS PluginBase and PluginManager counterpart for plugins compiled into the binary. Each plugin package calls party.Register from its init function, and the application's generated main calls party.Activate with the plugin IDs listed in its manifest. Activation validates the selection, sorts it so every plugin comes after the plugins it requires, merges plugin config, runs every Register before any Boot, and wires translations and mail templates in between. Capabilities beyond the lifecycle are declared through the interfaces in pact.

Features

  • party.Plugin, the descriptor every plugin implements: party.Plugin.ID, party.Plugin.Requires, party.Plugin.Register and party.Plugin.Boot.
  • A process-wide, concurrency-safe registry filled by party.Register (nil plugins are ignored).
  • party.Activate selects plugins by manifest ID and fails on an empty ID, a duplicate ID, an unregistered plugin, a missing requirement or a dependency cycle.
  • Stable topological ordering: plugins without a dependency relation keep their manifest order.
  • Activation sequence: records the ordered IDs on the backpack.App, merges each pact.HasConfig tree into the app config under the plugin ID, runs every Register, publishes the translator (phrasebook) and mailer (postcard), then registers each plugin's mail templates and runs its Boot.

Usage

A plugin registers itself when its package is imported:

package blog

import (
	"git.golem15.com/golem15/summercms/modules/backpack"
	"git.golem15.com/golem15/summercms/modules/party"
)

type Plugin struct{}

func (p *Plugin) ID() string                       { return "acme.blog" }
func (p *Plugin) Requires() []string               { return []string{"acme.user"} }
func (p *Plugin) Register(app *backpack.App) error { return nil }
func (p *Plugin) Boot(app *backpack.App) error     { return nil }

func init() {
	party.Register(&Plugin{})
}

The application activates the plugins it lists, in dependency order:

cfg, err := compass.Load("config")
if err != nil {
	return err
}
app := backpack.New(cfg)
plugins, err := party.Activate(app, []string{"acme.user", "acme.blog"})
if err != nil {
	return err
}

API reference

Identifier Description
party.Plugin Interface every compiled plugin implements: ID, required plugin IDs, Register and Boot.
party.Register Adds a plugin to the process-wide registry; called from the plugin's init.
party.Activate Selects registered plugins by ID, orders them by party.Plugin.Requires and runs the config, Register, translation, mail and Boot steps; returns the ordered plugins.

Dependencies

Testing

go test ./modules/party/...

The tests use in-memory plugins and testing/fstest file systems and need no external services.