Files
summercms/modules/signpost/content.go
Jakub Zych 753fb5969a 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
2026-10-26 22:22:25 +01:00

86 lines
2.4 KiB
Go

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
}