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:
85
modules/signpost/content.go
Normal file
85
modules/signpost/content.go
Normal file
@@ -0,0 +1,85 @@
|
||||
package signpost
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"git.golem15.com/golem15/summercms/modules/pact"
|
||||
)
|
||||
|
||||
// checkContent validates a type's content descriptor: Model and Describe are
|
||||
// required when Content is set.
|
||||
func checkContent(owner string, t pact.MenuItemType) error {
|
||||
c := t.Content
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
if strings.TrimSpace(c.Model) == "" {
|
||||
return fmt.Errorf("signpost: menu item type %q of plugin %s has a content descriptor without Model", t.Key, owner)
|
||||
}
|
||||
if c.Describe == nil {
|
||||
return fmt.Errorf("signpost: menu item type %q of plugin %s has a content descriptor without Describe", t.Key, owner)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContentTypes returns the types that carry a content descriptor
|
||||
// (pact.MenuItemType.Content), in registration order. The slice is a copy.
|
||||
func (r *Registry) ContentTypes() []pact.MenuItemType {
|
||||
out := []pact.MenuItemType{}
|
||||
if r == nil {
|
||||
return out
|
||||
}
|
||||
for _, t := range r.types {
|
||||
if t.Content != nil {
|
||||
out = append(out, t)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// ContentTypeForModel returns the content type whose descriptor declares
|
||||
// model, the morph type record events carry (pact.RecordSaved.Model).
|
||||
func (r *Registry) ContentTypeForModel(model string) (pact.MenuItemType, bool) {
|
||||
if r == nil || model == "" {
|
||||
return pact.MenuItemType{}, false
|
||||
}
|
||||
for _, t := range r.types {
|
||||
if t.Content != nil && t.Content.Model == model {
|
||||
return t, true
|
||||
}
|
||||
}
|
||||
return pact.MenuItemType{}, false
|
||||
}
|
||||
|
||||
// Describe describes one record of the content type key through its
|
||||
// descriptor, handing it the layered pattern (Pattern(key, "")). An unknown
|
||||
// key or a type without a content descriptor is an error; a record the type
|
||||
// does not know answers nil.
|
||||
func (r *Registry) Describe(ctx context.Context, key, id, unprefixedLocale string) (*pact.ContentRecord, error) {
|
||||
t, err := r.contentType(key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if ctx == nil {
|
||||
ctx = context.Background()
|
||||
}
|
||||
return t.Content.Describe(ctx, pact.ContentDescribe{
|
||||
ID: id,
|
||||
Pattern: r.Pattern(key, ""),
|
||||
UnprefixedLocale: unprefixedLocale,
|
||||
})
|
||||
}
|
||||
|
||||
// contentType is the type key with its content descriptor.
|
||||
func (r *Registry) contentType(key string) (pact.MenuItemType, error) {
|
||||
t, ok := r.Type(key)
|
||||
if !ok {
|
||||
return pact.MenuItemType{}, fmt.Errorf("signpost: unknown menu item type %q", key)
|
||||
}
|
||||
if t.Content == nil {
|
||||
return pact.MenuItemType{}, fmt.Errorf("signpost: menu item type %q has no content descriptor", key)
|
||||
}
|
||||
return t, nil
|
||||
}
|
||||
Reference in New Issue
Block a user