feat(32-02): record events and content descriptors (tracer)
- pact.RecordSaved/RecordDeleted/RecordChange, fired as pointers after commit - pact.ContentDescriptor and request/result types; MenuItemType.Content - AdminFormSave.Changes carries the owner's changes to extension Save - cabana.EmitRecordSaved/EmitRecordDeleted; admin save snapshots columns and translated values and fires RecordSaved through lagoon.AfterCommit - signpost validates Content and gains ContentTypes, ContentTypeForModel, Describe
This commit is contained in:
100
modules/pact/content.go
Normal file
100
modules/pact/content.go
Normal file
@@ -0,0 +1,100 @@
|
||||
package pact
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ContentDescriptor describes the records behind a menu item type, for
|
||||
// consumers that work on every content type at once: sitemaps, search
|
||||
// indexers, audit tools, metadata editors. A type sets it in
|
||||
// MenuItemType.Content; a type without one takes no part and behaves as
|
||||
// before.
|
||||
//
|
||||
// Controller is the ID of the admin controller whose form edits the
|
||||
// records, "" when none does. Model is the records' morph type, the value
|
||||
// RecordSaved and RecordDeleted carry (lagoon.MorphType), so an event maps to
|
||||
// its content type with one lookup; it is required. Describe is required and
|
||||
// describes one record by id. Records pages through the records and Match
|
||||
// maps a public path to a record; both are optional.
|
||||
//
|
||||
// The functions read through cabana.TxFromContext(ctx) when ctx carries a
|
||||
// write transaction, so code running inside a save (a form extension's Save,
|
||||
// for example) sees the values the save has just written.
|
||||
type ContentDescriptor struct {
|
||||
Controller string
|
||||
Model string
|
||||
Records func(ctx context.Context, in ContentList) (ContentPage, error) `json:"-"`
|
||||
Describe func(ctx context.Context, in ContentDescribe) (*ContentRecord, error) `json:"-"`
|
||||
Match func(ctx context.Context, in ContentMatch) (*ContentMatchResult, error) `json:"-"`
|
||||
}
|
||||
|
||||
// ContentList is what ContentDescriptor.Records receives. Pattern is the URL
|
||||
// pattern already layered by the registry (the host's override, else the
|
||||
// type's default). After is the ID of the last record of the previous page,
|
||||
// "" for the first page; Limit is the page size the caller wants (the type
|
||||
// may cap it). UnprefixedLocale names the locale whose URLs carry no locale
|
||||
// prefix; "" leaves the choice to the type.
|
||||
type ContentList struct {
|
||||
Pattern string
|
||||
After string
|
||||
Limit int
|
||||
UnprefixedLocale string
|
||||
}
|
||||
|
||||
// ContentPage is one page of records in a stable order. Next is the After of
|
||||
// the following page, "" on the last page.
|
||||
type ContentPage struct {
|
||||
Records []ContentRecord
|
||||
Next string
|
||||
}
|
||||
|
||||
// ContentDescribe is what ContentDescriptor.Describe receives: the record's
|
||||
// ID, the layered URL pattern and the unprefixed locale, as in ContentList.
|
||||
type ContentDescribe struct {
|
||||
ID string
|
||||
Pattern string
|
||||
UnprefixedLocale string
|
||||
}
|
||||
|
||||
// ContentRecord describes one record. ID is its primary key as text,
|
||||
// Published whether visitors can see it, LastMod its last change (nil when
|
||||
// unknown). Locales lists the record per locale in the site's locale order.
|
||||
type ContentRecord struct {
|
||||
ID string
|
||||
Published bool
|
||||
LastMod *time.Time
|
||||
Locales []ContentLocale
|
||||
}
|
||||
|
||||
// ContentLocale is a record in one locale. URL is its public path, "" when
|
||||
// the locale or the host has no public page for it. Title, Description and
|
||||
// Image (a URL) are the record's own defaults for page metadata; Words is the
|
||||
// body's word count, nil when the type has no body.
|
||||
type ContentLocale struct {
|
||||
Locale string
|
||||
URL string
|
||||
Title string
|
||||
Description string
|
||||
Image string
|
||||
Words *int
|
||||
}
|
||||
|
||||
// ContentMatch is what ContentDescriptor.Match receives: a public path (no
|
||||
// query, no host), the layered URL pattern and the unprefixed locale.
|
||||
type ContentMatch struct {
|
||||
Path string
|
||||
Pattern string
|
||||
UnprefixedLocale string
|
||||
}
|
||||
|
||||
// ContentMatchResult names the record a path belongs to and the locale the
|
||||
// path addresses. Exact is false when the path names the record but a
|
||||
// segment does not match it (another category, a stale locale prefix, a
|
||||
// slug of another locale): the caller may then redirect to the record's URL.
|
||||
// Match answers nil when the path names no record visitors can see.
|
||||
type ContentMatchResult struct {
|
||||
ID string
|
||||
Locale string
|
||||
Exact bool
|
||||
}
|
||||
Reference in New Issue
Block a user