- docs/database: models, migrations, queries and pagination, relations, casts and validation, attachments and transactions (lagoon.Transaction, lagoon.AfterCommit, nested savepoints, lagoon.OnDatabase) - docs/services: configuration, events, routing with auth groups, rate limiting, authentication, the OAuth server, mail and localization - runnable Examples for lagoon, attach, compass, surf, wire, bouncer, wristband, postcard, phrasebook and festival; lagoon TestDocs* regions run on the package's Postgres harness through DocsDB - 15 new required pages
93 lines
2.5 KiB
Go
93 lines
2.5 KiB
Go
package festival_test
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"git.golem15.com/golem15/summercms/modules/festival"
|
|
)
|
|
|
|
// PostPublished is the event the acme.blog plugin fires after a post goes live.
|
|
type PostPublished struct {
|
|
Title string
|
|
}
|
|
|
|
func ExampleBus_Fire() {
|
|
bus := festival.New() // in a plugin, use app.Events
|
|
|
|
// acme.search and acme.notify extend acme.blog from their Boot steps.
|
|
bus.Listen("acme.search", func(ctx context.Context, e PostPublished) error {
|
|
fmt.Println("index", e.Title)
|
|
return nil
|
|
})
|
|
bus.ListenPriority("acme.notify", 10, func(ctx context.Context, e PostPublished) error {
|
|
fmt.Println("notify subscribers of", e.Title)
|
|
return nil
|
|
})
|
|
|
|
// acme.blog fires the event; higher priorities run first.
|
|
if err := bus.Fire(context.Background(), PostPublished{Title: "Hello"}); err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
// Output:
|
|
// notify subscribers of Hello
|
|
// index Hello
|
|
}
|
|
|
|
// PostFormExtended gathers extra fields other plugins add to the post form.
|
|
type PostFormExtended struct {
|
|
fields map[string]any
|
|
}
|
|
|
|
func (e *PostFormExtended) Collected() map[string]any { return e.fields }
|
|
|
|
func ExampleBus_Collect() {
|
|
bus := festival.New()
|
|
bus.Listen("acme.seo", func(ctx context.Context, e *PostFormExtended) error {
|
|
e.fields = map[string]any{"meta_title": "text"}
|
|
return nil
|
|
})
|
|
bus.Listen("acme.gallery", func(ctx context.Context, e *PostFormExtended) error {
|
|
e.fields = map[string]any{"cover": "fileupload"}
|
|
return nil
|
|
})
|
|
|
|
fields, err := bus.Collect(context.Background(), &PostFormExtended{})
|
|
fmt.Println(fields, err)
|
|
// Output: map[cover:fileupload meta_title:text] <nil>
|
|
}
|
|
|
|
// SlugResolving asks plugins to resolve a URL slug; the first one that
|
|
// knows it handles the event.
|
|
type SlugResolving struct {
|
|
Slug string
|
|
Found string
|
|
}
|
|
|
|
func (e *SlugResolving) IsHandled() bool { return e.Found != "" }
|
|
|
|
func ExampleBus_UntilHandled() {
|
|
bus := festival.New()
|
|
bus.ListenPriority("acme.pages", 10, func(ctx context.Context, e *SlugResolving) error {
|
|
if e.Slug == "about" {
|
|
e.Found = "page"
|
|
}
|
|
return nil
|
|
})
|
|
bus.Listen("acme.blog", func(ctx context.Context, e *SlugResolving) error {
|
|
fmt.Println("acme.blog asked for", e.Slug)
|
|
e.Found = "post"
|
|
return nil
|
|
})
|
|
|
|
for _, slug := range []string{"about", "hello-world"} {
|
|
e := &SlugResolving{Slug: slug}
|
|
handled, err := bus.UntilHandled(context.Background(), e)
|
|
fmt.Println(slug, handled, e.Found, err)
|
|
}
|
|
// Output:
|
|
// about true page <nil>
|
|
// acme.blog asked for hello-world
|
|
// hello-world true post <nil>
|
|
}
|