content

package
v0.11.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 5, 2026 License: Apache-2.0 Imports: 16 Imported by: 0

Documentation

Overview

Package content defines the content object at the center of the CMS.

Index

Constants

View Source
const AnyContentType = "*"

AnyContentType is the rule value matching every content type.

View Source
const DefaultLocale = "en-US"

DefaultLocale is the language the site answers in when nothing else applies.

View Source
const DefaultPerPage = 20

DefaultPerPage is how many items a public listing page carries when nothing else applies.

View Source
const LocaleSettingKey = "locale.default"

LocaleSettingKey names the stored site default language.

View Source
const MaxDepth = 10

MaxDepth bounds how many levels of content nest under one another.

View Source
const MaxFieldDepth = 32

MaxFieldDepth is how many containers a field may stand inside.

View Source
const MaxPerPage = 100

MaxPerPage is the most items one listing page may carry.

View Source
const OperatorContains = "contains"

OperatorContains is the operator matching a value holding the rule value.

View Source
const OperatorEmpty = "empty"

OperatorEmpty is the operator matching a value that is not set.

View Source
const OperatorGreater = ">"

OperatorGreater is the operator matching a value above the rule value.

View Source
const OperatorIs = "=="

OperatorIs is the operator matching a rule value exactly.

View Source
const OperatorIsNot = "!="

OperatorIsNot is the operator excluding a rule value.

View Source
const OperatorLess = "<"

OperatorLess is the operator matching a value below the rule value.

View Source
const OperatorNotEmpty = "not_empty"

OperatorNotEmpty is the operator matching a value that is set.

View Source
const PageWord = "page"

PageWord is the segment a numbered listing hides behind.

View Source
const PerPageSettingKey = "content.per_page"

PerPageSettingKey names the stored public listing page size.

View Source
const ScreenContentType = "content_type"

ScreenContentType is the screen entry naming the content type fields would appear on.

View Source
const SettingAllowCustom = "allow_custom"

SettingAllowCustom names whether a choice field takes values outside its choices.

View Source
const SettingAllowNull = "allow_null"

SettingAllowNull names whether a choice control offers an explicit empty entry.

View Source
const SettingChoices = "choices"

SettingChoices names the value and label pairs a choice field offers.

View Source
const SettingConditions = "conditions"

SettingConditions is the setting holding the rules a field is shown under.

View Source
const SettingDefault = "default"

SettingDefault names the value the editor pre-fills a fresh item with.

View Source
const SettingInstructions = "instructions"

SettingInstructions names the help text shown under the control.

View Source
const SettingListed = "listed"

SettingListed is the setting opting a field into the admin list as a column.

View Source
const SettingMax = "max"

SettingMax names the largest value a number field accepts.

View Source
const SettingMaxLength = "maxlength"

SettingMaxLength names the longest text a text field accepts.

View Source
const SettingMin = "min"

SettingMin names the smallest value a number field accepts.

View Source
const SettingMultiple = "multiple"

SettingMultiple names whether a choice field holds several values.

View Source
const SettingPlaceholder = "placeholder"

SettingPlaceholder names the ghost text an empty control shows.

View Source
const SettingPresentation = "presentation"

SettingPresentation names the control a field is edited as.

View Source
const SettingStep = "step"

SettingStep names the increment the editor control moves by.

View Source
const SettingVariant = "variant"

SettingVariant names the flavor a text field is edited and checked as.

View Source
const TypePost = "post"

TypePost is the key of the built-in post type.

Variables

View Source
var ErrConflict = errors.New("content: conflicting update")

ErrConflict reports that the content item changed after the update was prepared.

View Source
var ErrCycle = errors.New("content: the item cannot nest inside itself")

ErrCycle reports that content would nest inside itself.

View Source
var ErrDefaultRequired = errors.New("content: the default type must stay")

ErrDefaultRequired reports that the default content type may not be deactivated or removed.

View Source
var ErrDefinitionReadOnly = errors.New("content: a plugin declared the definition")

ErrDefinitionReadOnly reports a write to a definition a plugin declared.

View Source
var ErrFieldBounds = errors.New("content: value out of bounds")

ErrFieldBounds reports a value falling outside the bounds its field carries.

View Source
var ErrFieldFilterInvalid = errors.New("content: field filter invalid")

ErrFieldFilterInvalid reports a field filter term a list cannot read.

View Source
var ErrFieldHidden = errors.New("content: field is hidden")

ErrFieldHidden reports a value submitted under a field its conditions hide.

View Source
var ErrFieldNotFound = errors.New("content: field not found")

ErrFieldNotFound reports that the type declares no field under the key.

View Source
var ErrFieldNotRelational = errors.New("content: the kind takes no target or many")

ErrFieldNotRelational reports a target or many on a kind that takes neither.

View Source
var ErrFieldOrder = errors.New("content: incomplete field order")

ErrFieldOrder reports that an order does not name every declared field exactly once.

View Source
var ErrFieldReferenced = errors.New("content: a sibling's conditions read the field")

ErrFieldReferenced reports a field a sibling's conditions read.

View Source
var ErrFieldRequired = errors.New("content: field is required")

ErrFieldRequired reports that a field must hold a value before publishing.

View Source
var ErrFieldShape = errors.New("content: wrong kind of value")

ErrFieldShape reports that a value is not the kind its field holds.

View Source
var ErrFieldTaken = errors.New("content: field key taken")

ErrFieldTaken reports that the type already declares a field under the key.

View Source
var ErrFieldTooDeep = errors.New("content: field nested too deep")

ErrFieldTooDeep reports that a field would stand deeper than a container tree runs.

View Source
var ErrGroupKeyTaken = errors.New("content: field group key already taken")

ErrGroupKeyTaken reports a field group key another group already holds.

View Source
var ErrGroupNotFound = errors.New("content: field group not found")

ErrGroupNotFound reports that no field group holds the identifier.

View Source
var ErrGroupOrder = errors.New("content: incomplete field group order")

ErrGroupOrder reports an order that does not name every field group exactly once.

View Source
var ErrHoldsChildren = errors.New("content: the item still holds children")

ErrHoldsChildren reports that content still holds content nested under it.

View Source
var ErrInvalidAuthor = errors.New("content: invalid author")

ErrInvalidAuthor reports that a content item carries no author.

View Source
var ErrInvalidFieldKey = errors.New("content: invalid field key")

ErrInvalidFieldKey reports that a field key is not a lowercase word.

View Source
var ErrInvalidFieldKind = errors.New("content: invalid field kind")

ErrInvalidFieldKind reports that a field kind is not one the CMS holds.

View Source
var ErrInvalidFieldLabel = errors.New("content: invalid field label")

ErrInvalidFieldLabel reports that a field carries no label.

View Source
var ErrInvalidGroupKey = errors.New("content: invalid field group key")

ErrInvalidGroupKey reports a field group key that is not shaped like a key.

View Source
var ErrInvalidGroupTitle = errors.New("content: a field group needs a title")

ErrInvalidGroupTitle reports a field group carrying no title.

View Source
var ErrInvalidKey = errors.New("content: invalid type key")

ErrInvalidKey reports that a type key is not a lowercase word.

View Source
var ErrInvalidLabel = errors.New("content: invalid type label")

ErrInvalidLabel reports that a type carries no label.

View Source
var ErrInvalidOrder = errors.New("content: invalid order")

ErrInvalidOrder reports that a sort direction is not one the CMS sorts in.

View Source
var ErrInvalidOrderBy = errors.New("content: invalid orderby")

ErrInvalidOrderBy reports that a sort column is not one the CMS sorts by.

View Source
var ErrInvalidPageKind = errors.New("content: invalid page kind")

ErrInvalidPageKind reports that a page kind is not one the CMS renders.

View Source
var ErrInvalidRevisionCap = errors.New("content: invalid revision cap")

ErrInvalidRevisionCap reports that a revision cap is not a number of rows.

View Source
var ErrInvalidRouteWord = errors.New("content: invalid route word")

ErrInvalidRouteWord reports that a route word is not a lowercase word.

View Source
var ErrInvalidStatus = errors.New("content: invalid status")

ErrInvalidStatus reports that a status value is not one the CMS stores.

View Source
var ErrInvalidTransition = errors.New("content: invalid status transition")

ErrInvalidTransition reports that a status change is not allowed.

View Source
var ErrInvalidType = errors.New("content: invalid type")

ErrInvalidType reports that a content type is not registered.

View Source
var ErrLocaleUnknown = errors.New("content: locale unknown")

ErrLocaleUnknown reports that a language is not one the site answers in.

View Source
var ErrNotFound = errors.New("content: not found")

ErrNotFound reports that no content item exists for the requested ID.

View Source
var ErrNotHierarchical = errors.New("content: the type does not nest")

ErrNotHierarchical reports that a content type does not nest.

View Source
var ErrParamTaken = errors.New("content: param name taken")

ErrParamTaken reports a second param registering under a taken name.

View Source
var ErrParentTrashed = errors.New("content: the parent is in the trash")

ErrParentTrashed reports that a parent is on its way out of the site.

View Source
var ErrParentType = errors.New("content: the parent holds another kind of content")

ErrParentType reports that a parent holds another kind of content.

View Source
var ErrPerPageInvalid = errors.New("content: per page invalid")

ErrPerPageInvalid reports that a listing page size is not a whole number from 1 to MaxPerPage.

View Source
var ErrRelationNeedsTarget = errors.New("content: a relation field needs a target type")

ErrRelationNeedsTarget reports that a relation field names no target type.

View Source
var ErrRepeatedTarget = errors.New("content: repeated target")

ErrRepeatedTarget reports that a relation field was given the same target twice.

View Source
var ErrReservedAddress = errors.New("content: the address is reserved")

ErrReservedAddress reports that an address names a place the CMS keeps.

View Source
var ErrRevisionNotFound = errors.New("content: revision not found")

ErrRevisionNotFound reports that no revision exists for the requested ID.

View Source
var ErrRootTaken = errors.New("content: another type holds the root")

ErrRootTaken reports that another content type already lives at the root.

View Source
var ErrRouteWordReserved = errors.New("content: route word reserved")

ErrRouteWordReserved reports that the route word names a place the CMS keeps.

View Source
var ErrRouteWordTaken = errors.New("content: route word taken")

ErrRouteWordTaken reports that another content type answers under the route word.

View Source
var ErrRuleAnyNegated = errors.New("content: the any value takes only the is operator")

ErrRuleAnyNegated reports the any value beside the is not operator.

View Source
var ErrRuleCycle = errors.New("content: conditions loop")

ErrRuleCycle reports conditions that lead back to the field they show.

View Source
var ErrRuleOperator = errors.New("content: rule operator not offered")

ErrRuleOperator reports a location rule using an operator its source does not offer.

View Source
var ErrRuleSourceUnknown = errors.New("content: rule source unknown")

ErrRuleSourceUnknown reports a location rule naming an unregistered source.

View Source
var ErrRuleValue = errors.New("content: rule value missing")

ErrRuleValue reports a location rule holding no value.

View Source
var ErrSelfTarget = errors.New("content: an item cannot point at itself")

ErrSelfTarget reports that a relation field points an item at itself.

View Source
var ErrSettingBounds = errors.New("content: settings disagree")

ErrSettingBounds reports settings that disagree with each other.

View Source
var ErrSettingShape = errors.New("content: setting shape")

ErrSettingShape reports a setting holding a value of the wrong shape.

View Source
var ErrSettingUnknown = errors.New("content: setting unknown")

ErrSettingUnknown reports a setting the field's kind does not take.

View Source
var ErrSlugTaken = errors.New("content: slug taken")

ErrSlugTaken reports that a content type already holds the requested slug.

View Source
var ErrTargetNotFound = errors.New("content: target not found")

ErrTargetNotFound reports that a relation names an item nothing holds.

View Source
var ErrTargetType = errors.New("content: target is not the type the field points at")

ErrTargetType reports that a relation names an item of the wrong type.

View Source
var ErrTargetUnknown = errors.New("content: relation target unknown")

ErrTargetUnknown reports that a relation field targets an unregistered type.

View Source
var ErrTooDeep = errors.New("content: the nesting limit is reached")

ErrTooDeep reports that content nests beyond the limit.

View Source
var ErrTooManyTargets = errors.New("content: field holds one target")

ErrTooManyTargets reports that a relation field holding one was given more.

View Source
var ErrTypeInUse = errors.New("content: type still holds content")

ErrTypeInUse reports that the content type still holds content.

View Source
var ErrTypeInactive = errors.New("content: type is not active")

ErrTypeInactive reports that the content type is not active.

View Source
var ErrTypeNotFound = errors.New("content: type not found")

ErrTypeNotFound reports that no content type carries the requested key.

View Source
var ErrTypeTaken = errors.New("content: type key taken")

ErrTypeTaken reports that a content type already carries the requested key.

View Source
var ErrTypeTargeted = errors.New("content: a field still targets the type")

ErrTypeTargeted reports that a relation field of another type still targets the type.

View Source
var ErrUnknownField = errors.New("content: unknown field")

ErrUnknownField reports that the type declares no field under the key.

View Source
var ReservedRouteWords = []string{"admin", "api", "gophenberg", "_gophenberg", "media"}

ReservedRouteWords are the first address segments the CMS keeps for itself.

View Source
var SupportedLocales = []string{DefaultLocale, "es-ES", "fr-FR"}

SupportedLocales are the languages the site answers in, the fallback first.

Functions

func Acyclic added in v0.11.0

func Acyclic(fields []Field) error

Acyclic reports the first field whose conditions lead back to itself, if one does.

func AddressPrefix

func AddressPrefix(path, slug string) string

AddressPrefix returns the address an item's slug hangs from.

func AddressUnder

func AddressUnder(prefix, slug string) string

AddressUnder returns the address of a child carrying slug beneath prefix.

func CodeOf added in v0.6.0

func CodeOf(err error) (string, bool)

CodeOf returns the condition code an error names, reporting false when it names none.

func Concealed added in v0.11.0

func Concealed(fields []Field, scope, submitted Values) error

Concealed reports the first field of the scope that its rules hide and a request still names.

func ConditionsSetting added in v0.11.0

func ConditionsSetting(rules Rules) []any

ConditionsSetting returns the stored form of the rules, the value to hold under SettingConditions.

func Declaring added in v0.11.0

func Declaring(ctx context.Context, origin string) context.Context

Declaring returns a context carrying the plugin whose declarations the writes it reaches belong to.

func Filled added in v0.5.0

func Filled(values Values, relations Relations, fields []Field) error

Filled reports whether every required field the conditions show holds a value.

func FirstSegment

func FirstSegment(path string) string

FirstSegment returns the first segment of an address.

func GroupKeyFrom added in v0.11.0

func GroupKeyFrom(title string) string

GroupKeyFrom returns the key a group title mints, shaped like every other key.

func Hidden added in v0.11.0

func Hidden(fields []Field, scope Values) map[string]bool

Hidden returns the keys of the fields their conditions hide on the scope, a hidden source reading as absent.

func Listed added in v0.11.0

func Listed(f Field) bool

Listed reports whether a field is opted into the admin list.

func MediaIdentity added in v0.11.0

func MediaIdentity(value any) (int64, bool)

MediaIdentity returns the identity the value names, and whether the library can store it.

func NamesFieldFilter added in v0.11.0

func NamesFieldFilter(query url.Values) bool

NamesFieldFilter reports whether the query names any field filter term.

func OwnedBy added in v0.11.0

func OwnedBy(origin string) error

OwnedBy returns the refusal a definition the named plugin declared answers a write with.

func ParseFieldFilter added in v0.11.0

func ParseFieldFilter(query url.Values, fields []Field) (map[string]any, error)

ParseFieldFilter returns the containment object the field[<key>] parameters name, each coerced by its field's kind.

func ParsePerPage added in v0.11.0

func ParsePerPage(raw string) (int, error)

ParsePerPage returns the page size the text names, or the reason it is not one.

func Referenced added in v0.11.0

func Referenced(fields []Field, key string) (string, bool)

Referenced returns the sibling whose conditions read the key, and whether one does.

func Refuse added in v0.6.0

func Refuse(err error, code, message string, held Details) error

Refuse returns the sentinel carrying its condition code, its message and the details a client reads.

func ReservedRoot

func ReservedRoot(segment string) bool

ReservedRoot reports whether the segment names a place the CMS keeps for itself.

func ResolveLocale added in v0.6.0

func ResolveLocale(asked LocaleAsked) string

ResolveLocale returns the language to answer in, preferring the reader, then the site, then the languages the request accepts.

func ResolvePerPage added in v0.11.0

func ResolvePerPage(held string, found bool) int

ResolvePerPage returns the page size a stored setting names, or the default when it names none.

func Slugify

func Slugify(title string) string

Slugify returns title as a URL slug, or [untitledSlug] when it holds no slug characters.

func SourceOperators added in v0.11.0

func SourceOperators(kind FieldKind, multiple bool) []string

SourceOperators returns the operators a field of the kind offers as a rule source, none for a kind no rule reads.

func SplitValues added in v0.5.0

func SplitValues(patch Values, fields []Field) (Values, Relations, error)

SplitValues divides a patch into the scalar values and the targets its type declares.

func Stands added in v0.11.0

func Stands(siblings []Field, f Field) error

Stands reports whether a field's conditions close no loop and read siblings of its scope.

func Uncollided added in v0.10.0

func Uncollided(
	types []Type, held []Group, target Group, keys []string, leaving int, params *ParamRegistry,
) error

Uncollided reports whether the keys stay free of every other group sharing a type with this one.

func Unreferenced added in v0.11.0

func Unreferenced(fields []Field, key string) error

Unreferenced reports whether a sibling's conditions read the key, refusing the removal when one does.

func ValidGroupKey added in v0.11.0

func ValidGroupKey(key string) error

ValidGroupKey returns the reason a field group cannot carry the key, or nothing when it can.

func ValidateLocale added in v0.6.0

func ValidateLocale(locale string) error

ValidateLocale reports whether the site answers in the language.

func ValidateSettings added in v0.11.0

func ValidateSettings(kind FieldKind, settings map[string]any) error

ValidateSettings reports whether the settings are ones the kind takes, well shaped and agreeing.

Types

type Address

type Address struct {
	Kind Kind
	Type Type
	Item Content
	Page int
}

Address is what a public address holds.

type AddressReader

type AddressReader interface {
	PublishedByPath(ctx context.Context, path string) (Content, error)
}

AddressReader reads the published content an address holds.

type Choice added in v0.10.0

type Choice struct {
	Value string
	Label string
}

Choice is one value a rule builder offers for a source.

type Content

type Content struct {
	ID          uuid.UUID
	Type        string
	ParentID    *uuid.UUID
	Path        string
	Slug        string
	Title       string
	Content     string
	Excerpt     string
	Status      Status
	AuthorID    uuid.UUID
	Fields      Values
	Relations   Relations
	PublishedAt *time.Time
	CreatedAt   time.Time
	UpdatedAt   time.Time
}

Content is a content item holding Gutenberg-serialized block HTML.

func New

func New(t Type, parent *Content, title string, authorID uuid.UUID) (Content, error)

New returns a draft Content of the given type under parent, slugged after its title.

func Reparent

func Reparent(t Type, c Content, parent *Content, height int) (Content, error)

Reparent returns the item and the height it carries nested under parent, or the reason they may not sit there.

func (Content) Place

func (c Content) Place(prefix, slug string) Content

Place returns the item carrying slug at the address beneath prefix.

func (Content) Rename

func (c Content) Rename(slug string) (Content, error)

Rename returns the item carrying slug where it already answers, or the reason it may not.

func (*Content) Restore

func (c *Content) Restore() error

Restore returns a trashed content item to draft, or reports ErrInvalidTransition.

func (Content) SelfTargeted added in v0.5.0

func (c Content) SelfTargeted() error

SelfTargeted reports whether any relation field of the item points at the item itself.

func (*Content) Transition

func (c *Content) Transition(to Status) error

Transition moves the content item to the given status, stamping PublishedAt on the first publication and returning ErrInvalidTransition when disallowed.

type Details added in v0.6.0

type Details map[string]any

Details holds the parts of an error a client reads as data rather than as prose.

func DetailsOf added in v0.6.0

func DetailsOf(err error) (Details, bool)

DetailsOf returns the details an error carries, reporting false when it carries none.

type Error added in v0.9.0

type Error struct {
	Err     error
	Code    string
	Message string
	Held    Details
}

Error is a sentinel carrying its condition code and the dynamic parts of the message.

func (*Error) Error added in v0.9.0

func (e *Error) Error() string

Error returns the message the error reads as.

func (*Error) Unwrap added in v0.9.0

func (e *Error) Unwrap() error

Unwrap returns the sentinel the error stands for.

type Field added in v0.5.0

type Field struct {
	ID        int
	GroupID   int
	ParentID  int
	TypeKey   string
	Key       string
	Label     string
	Kind      FieldKind
	RelatesTo string
	Many      bool
	Required  bool
	Origin    string
	Settings  map[string]any
	Fields    []Field
	CreatedAt time.Time
	UpdatedAt time.Time
}

Field describes one typed field a group declares, flattened onto the types its group matches.

func NewField added in v0.5.0

func NewField(f Field) (Field, error)

NewField returns a field definition ready to store, or the reason it is not one.

func NewSubField added in v0.11.0

func NewSubField(f Field, parent FieldKind) (Field, error)

NewSubField returns a field definition ready to store inside the parent kind, or the reason it is not one.

func (Field) Validate added in v0.5.0

func (f Field) Validate() error

Validate reports whether the field definition may be stored.

type FieldKind added in v0.5.0

type FieldKind string

FieldKind is the shape of value a field holds.

const (
	FieldKindText     FieldKind = "text"
	FieldKindNumber   FieldKind = "number"
	FieldKindBoolean  FieldKind = "boolean"
	FieldKindDate     FieldKind = "date"
	FieldKindMedia    FieldKind = "media"
	FieldKindRelation FieldKind = "relation"
	FieldKindChoice   FieldKind = "choice"
	FieldKindSection  FieldKind = "section"
	FieldKindRepeater FieldKind = "repeater"
)

The field kinds a content type declares.

func (FieldKind) Holds added in v0.11.0

func (k FieldKind) Holds() bool

Holds reports whether the kind carries sub fields of its own.

type Filter

type Filter struct {
	Type    string
	Status  Status
	Search  string
	OrderBy OrderBy
	Order   Order
	Page    int
	PerPage int
	Fields  map[string]any
}

Filter narrows a content listing.

type Group added in v0.10.0

type Group struct {
	ID        int
	Key       string
	Title     string
	Location  Rules
	Position  int
	Active    bool
	Origin    string
	Fields    []Field
	CreatedAt time.Time
	UpdatedAt time.Time
}

Group is a bundle of ordered fields shown where its location rules match.

type Kind

type Kind string

Kind names what an address holds.

const (
	KindItem    Kind = "item"
	KindArchive Kind = "archive"
	KindTerm    Kind = "term"
)

The kinds of thing a public address answers with.

type LocaleAsked added in v0.6.0

type LocaleAsked struct {
	User     string
	Site     string
	Accepted string
}

LocaleAsked carries what each leg of the resolution chain offered.

type Order

type Order string

Order names a sort direction.

const (
	OrderAsc  Order = "asc"
	OrderDesc Order = "desc"
)

The directions a listing can be sorted in.

func ParseOrder

func ParseOrder(raw string) (Order, error)

ParseOrder returns the direction named by raw, or ErrInvalidOrder.

type OrderBy

type OrderBy string

OrderBy names a column a listing can be sorted by.

const (
	OrderByDate  OrderBy = "date"
	OrderByTitle OrderBy = "title"
)

The columns a listing can be sorted by.

func ParseOrderBy

func ParseOrderBy(raw string) (OrderBy, error)

ParseOrderBy returns the column named by raw, or ErrInvalidOrderBy.

type PageKind

type PageKind string

PageKind is what the public page of one content item renders.

const (
	PageKindSingle  PageKind = "single"
	PageKindArchive PageKind = "archive"
)

The page kinds a content type declares.

type Param added in v0.10.0

type Param interface {
	// Name returns the source string rules reference the param by.
	Name() string
	// Operators returns the operators the param accepts.
	Operators() []string
	// Values returns the choices a rule builder offers for the param.
	Values(ctx context.Context) ([]Choice, error)
	// Stands reports why a rule value does not stand beside the operator, if it does not.
	Stands(operator, value string) error
	// Holds reports whether the screen satisfies the operator and the value.
	Holds(scr Screen, operator, value string) bool
}

Param is one rule source the location engine validates and matches against.

func NewContentTypeParam added in v0.10.0

func NewContentTypeParam(choices TypeChoices) Param

NewContentTypeParam returns the built in param matching the content type of a screen.

type ParamRegistry added in v0.10.0

type ParamRegistry struct {
	// contains filtered or unexported fields
}

ParamRegistry holds the rule sources locations validate and match against.

func DefaultParamRegistry added in v0.10.0

func DefaultParamRegistry(choices TypeChoices) *ParamRegistry

DefaultParamRegistry returns a registry holding the built in content type param.

func NewParamRegistry added in v0.10.0

func NewParamRegistry() *ParamRegistry

NewParamRegistry returns a registry holding no params.

func ScopeParams added in v0.11.0

func ScopeParams(fields []Field) *ParamRegistry

ScopeParams returns the registry of the sibling fields a condition may read.

func (*ParamRegistry) All added in v0.10.0

func (r *ParamRegistry) All() []Param

All returns every registered param in registration order.

func (*ParamRegistry) Param added in v0.10.0

func (r *ParamRegistry) Param(name string) (Param, bool)

Param returns the registered param of a name, and whether one holds it.

func (*ParamRegistry) Register added in v0.10.0

func (r *ParamRegistry) Register(p Param) error

Register adds a param, refusing a name already taken.

type Registry

type Registry struct {
	// contains filtered or unexported fields
}

Registry answers which content types the CMS holds, caching what it reads.

func NewRegistry

func NewRegistry(store TypeStore) *Registry

NewRegistry returns a Registry reading through store.

func (*Registry) Active

func (r *Registry) Active(ctx context.Context, key string) (Type, error)

Active returns the type carrying the key when it is active, or the reason it serves nothing.

func (*Registry) AdoptGroup added in v0.11.0

func (r *Registry) AdoptGroup(ctx context.Context, key string) error

AdoptGroup takes a plugin's field group and the fields inside it over as the site's own.

func (*Registry) AdoptType added in v0.11.0

func (r *Registry) AdoptType(ctx context.Context, key string) error

AdoptType takes a plugin's content type over as the site's own.

func (*Registry) All

func (r *Registry) All(ctx context.Context) ([]Type, error)

All returns every registered type, active or not, in registration order.

func (*Registry) ByKey

func (r *Registry) ByKey(ctx context.Context, key string) (Type, error)

ByKey returns the type carrying the key, or ErrTypeNotFound.

func (*Registry) ByRouteWord

func (r *Registry) ByRouteWord(ctx context.Context, word string) (Type, error)

ByRouteWord returns the active type answering under the word, or ErrTypeNotFound.

func (*Registry) Create

func (r *Registry) Create(ctx context.Context, t Type) (Type, error)

Create registers the type, or reports why it may not join the registry.

func (*Registry) CreateField added in v0.5.0

func (r *Registry) CreateField(ctx context.Context, f Field) (Field, error)

CreateField declares the field on its type, or reports why the registry refuses it.

func (*Registry) CreateFieldInGroup added in v0.10.0

func (r *Registry) CreateFieldInGroup(ctx context.Context, groupID int, f Field) (Field, error)

CreateFieldInGroup declares the field inside the group, or reports why the registry refuses it.

func (*Registry) CreateGroup added in v0.10.0

func (r *Registry) CreateGroup(ctx context.Context, g Group) (Group, error)

CreateGroup stores a new field group, or reports why the registry refuses it.

func (*Registry) CreateSubField added in v0.11.0

func (r *Registry) CreateSubField(ctx context.Context, parentID int, f Field) (Field, error)

CreateSubField declares the field inside the container the parent names.

func (*Registry) Default

func (r *Registry) Default(ctx context.Context) (Type, error)

Default returns the type living at the root, or ErrTypeNotFound.

func (*Registry) Delete

func (r *Registry) Delete(ctx context.Context, key string) error

Delete removes the type, or reports why the registry keeps it.

func (*Registry) DeleteFieldInGroup added in v0.10.0

func (r *Registry) DeleteFieldInGroup(ctx context.Context, groupID int, key string) error

DeleteFieldInGroup removes the field and its values from the types its group matches.

func (*Registry) DeleteGroup added in v0.10.0

func (r *Registry) DeleteGroup(ctx context.Context, id int) error

DeleteGroup removes the group with its fields and their values, or reports it missing.

func (*Registry) DeleteSubField added in v0.11.0

func (r *Registry) DeleteSubField(ctx context.Context, id int) error

DeleteSubField removes the field standing inside a container, and the values every item held under it.

func (*Registry) Groups added in v0.10.0

func (r *Registry) Groups(ctx context.Context) ([]Group, error)

Groups returns every field group in position order with its fields attached.

func (*Registry) MoveField added in v0.10.0

func (r *Registry) MoveField(ctx context.Context, groupID int, key string, toGroup int) (Field, error)

MoveField carries the field into another group, keeping the values it holds.

func (*Registry) Params added in v0.10.0

func (r *Registry) Params(ctx context.Context) *ParamRegistry

Params returns the rule sources locations evaluate against, the built in ones by default.

func (*Registry) ReorderFieldsInGroup added in v0.10.0

func (r *Registry) ReorderFieldsInGroup(ctx context.Context, groupID int, keys []string) ([]Field, error)

ReorderFieldsInGroup stores the declaration order of a group's fields.

func (*Registry) ReorderGroups added in v0.10.0

func (r *Registry) ReorderGroups(ctx context.Context, ids []int) ([]Group, error)

ReorderGroups stores the given order, or reports why the order does not stand.

func (*Registry) ReorderSubFields added in v0.11.0

func (r *Registry) ReorderSubFields(ctx context.Context, parentID int, keys []string) ([]Field, error)

ReorderSubFields stands the fields inside the container in the order the keys name.

func (*Registry) Update

func (r *Registry) Update(ctx context.Context, t Type) (Type, error)

Update stores the edited type, or reports why the registry keeps it as it stands.

func (*Registry) UpdateFieldInGroup added in v0.10.0

func (r *Registry) UpdateFieldInGroup(
	ctx context.Context, groupID int, f Field, expectedUpdatedAt time.Time,
) (Field, error)

UpdateFieldInGroup carries the field's label, required flag and settings when the expectation still holds.

func (*Registry) UpdateGroup added in v0.10.0

func (r *Registry) UpdateGroup(ctx context.Context, g Group) (Group, error)

UpdateGroup stores the group's title, location and active flag, or reports why it stands as it is.

func (*Registry) UpdateSubField added in v0.11.0

func (r *Registry) UpdateSubField(
	ctx context.Context, id int, f Field, expectedUpdatedAt time.Time,
) (Field, error)

UpdateSubField carries a label, a required flag and settings onto the field standing inside a container.

func (*Registry) WithParams added in v0.10.0

func (r *Registry) WithParams(params *ParamRegistry) *Registry

WithParams returns the registry evaluating locations against the given rule sources.

type Relations added in v0.5.0

type Relations map[string][]uuid.UUID

Relations holds the items a content item points at, keyed by field key.

func (Relations) Merge added in v0.5.0

func (r Relations) Merge(patch Relations) Relations

Merge returns the stored targets with the patch applied, where a named field replaces its targets.

type Resolver

type Resolver struct {
	// contains filtered or unexported fields
}

Resolver answers what a public address holds.

func NewResolver

func NewResolver(store AddressReader, registry TypeReader) *Resolver

NewResolver returns a Resolver reading content through store and types through registry.

func (*Resolver) Resolve

func (r *Resolver) Resolve(ctx context.Context, raw string) (Address, error)

Resolve returns what the address holds, or ErrNotFound.

type Revision

type Revision struct {
	ID        uuid.UUID
	ContentID uuid.UUID
	Kind      RevisionKind
	AuthorID  uuid.UUID
	Title     string
	Content   string
	Excerpt   string
	Fields    Values
	CreatedAt time.Time
}

Revision is a snapshot of a content item's editable content.

func NewRevision

func NewRevision(c Content, kind RevisionKind, authorID uuid.UUID) (Revision, error)

NewRevision returns a snapshot of the item's editable content, credited to the given author.

type RevisionKind

type RevisionKind string

RevisionKind distinguishes an update snapshot from a per-author autosave.

const (
	RevisionKindRevision RevisionKind = "revision"
	RevisionKindAutosave RevisionKind = "autosave"
)

The kinds of revision a content item carries.

type Rule added in v0.10.0

type Rule struct {
	Source   string `json:"source"`
	Operator string `json:"operator"`
	Value    string `json:"value"`
}

Rule is one location condition a field group states.

type Rules added in v0.10.0

type Rules [][]Rule

Rules is the location of a field group, OR groups of AND rules.

func ConditionsOf added in v0.11.0

func ConditionsOf(f Field) Rules

ConditionsOf returns the rules a field is shown under, none when it carries none.

func (Rules) Equal added in v0.11.0

func (r Rules) Equal(o Rules) bool

Equal reports whether the rules match once both are normalized.

func (Rules) Match added in v0.10.0

func (r Rules) Match(scr Screen, params *ParamRegistry) bool

Match reports whether any rule group fully matches the screen.

func (Rules) Normalize added in v0.10.0

func (r Rules) Normalize() Rules

Normalize returns the rules without zero rules, empty groups and values under valueless operators, never nil.

func (Rules) Validate added in v0.10.0

func (r Rules) Validate(params *ParamRegistry) error

Validate reports the first rule that is not well formed against the registered params.

type Screen added in v0.10.0

type Screen map[string]any

Screen carries what is known about the place fields would appear.

type Status

type Status string

Status is the publication state of a content item.

const (
	StatusDraft     Status = "draft"
	StatusPending   Status = "pending"
	StatusPrivate   Status = "private"
	StatusScheduled Status = "scheduled"
	StatusPublished Status = "published"
	StatusTrash     Status = "trash"
)

The statuses a content item may hold. Scheduled is stored but unreachable until a publish worker exists.

func ParseStatus

func ParseStatus(value string) (Status, error)

ParseStatus returns the Status named by value, or ErrInvalidStatus.

type Store

type Store interface {
	Create(ctx context.Context, c Content) (Content, error)
	ByID(ctx context.Context, id uuid.UUID) (Content, error)
	PublishedByPath(ctx context.Context, path string) (Content, error)
	Children(ctx context.Context, id uuid.UUID) (int, error)
	Depth(ctx context.Context, id uuid.UUID) (int, error)
	List(ctx context.Context, f Filter) ([]Content, int, error)
	RelatedTo(ctx context.Context, target uuid.UUID, page, perPage int) ([]Content, int, error)
	TargetsOf(ctx context.Context, from uuid.UUID) (Targets, error)
	Update(
		ctx context.Context, c Content, expectedUpdatedAt time.Time, snapshot *Revision, revisionCap int,
	) (Content, error)
	Trash(ctx context.Context, id uuid.UUID, updatedAt time.Time) (Content, error)
	Restore(ctx context.Context, id uuid.UUID, updatedAt time.Time) (Content, error)
	Delete(ctx context.Context, id uuid.UUID) error
	Counts(ctx context.Context, contentType string) (map[Status]int, error)
	Revisions(ctx context.Context, contentID uuid.UUID) ([]Revision, error)
	RevisionByID(ctx context.Context, contentID, revisionID uuid.UUID) (Revision, error)
	DeleteRevision(ctx context.Context, contentID, revisionID uuid.UUID) error
	SaveAutosave(ctx context.Context, autosave Revision) (Revision, error)
	Autosave(ctx context.Context, contentID, authorID uuid.UUID) (Revision, error)
	DeleteAutosave(ctx context.Context, contentID, authorID uuid.UUID) error
}

Store persists content items and their revisions.

type Target added in v0.5.0

type Target struct {
	ID    uuid.UUID
	Title string
	Path  string
}

Target names one item a relation field points at, as a public reader sees it.

type Targets added in v0.5.0

type Targets map[string][]Target

Targets holds the items a content item points at, named and addressed, keyed by field key.

type Type

type Type struct {
	Key           string
	SingularLabel string
	PluralLabel   string
	RouteWord     string
	Hierarchical  bool
	Revisions     bool
	RevisionCap   int
	PageKind      PageKind
	Default       bool
	Active        bool
	Origin        string
	Fields        []Field
	CreatedAt     time.Time
	UpdatedAt     time.Time
}

Type describes a kind of content the CMS stores.

func NewType

func NewType(key, singular, plural, routeWord string) (Type, error)

NewType returns a content type ready to store, or the reason it is not one.

func (Type) Validate

func (t Type) Validate() error

Validate reports whether the type may be stored.

type TypeChoices added in v0.10.0

type TypeChoices func(ctx context.Context) ([]Choice, error)

TypeChoices lists the type choices the content type param offers.

type TypeReader

type TypeReader interface {
	ByRouteWord(ctx context.Context, word string) (Type, error)
	ByKey(ctx context.Context, key string) (Type, error)
}

TypeReader answers which type answers under a route word and which carries a key.

type TypeStore

type TypeStore interface {
	List(ctx context.Context) ([]Type, error)
	ByKey(ctx context.Context, key string) (Type, error)
	Create(ctx context.Context, t Type) (Type, error)
	Update(ctx context.Context, t Type) (Type, error)
	Delete(ctx context.Context, key string) error
	ListGroups(ctx context.Context) ([]Group, error)
	CreateGroup(ctx context.Context, g Group) (Group, error)
	UpdateGroup(ctx context.Context, g Group) (Group, error)
	DeleteGroup(ctx context.Context, id int) error
	ReorderGroups(ctx context.Context, ids []int) error
	CreateFieldInGroup(ctx context.Context, groupID int, f Field) (Field, error)
	CreateSubField(ctx context.Context, parentID int, f Field) (Field, error)
	DeleteSubField(ctx context.Context, id int) error
	UpdateSubField(ctx context.Context, id int, f Field, expectedUpdatedAt time.Time) (Field, error)
	ReorderSubFields(ctx context.Context, parentID int, keys []string) error
	UpdateFieldInGroup(ctx context.Context, groupID int, f Field, expectedUpdatedAt time.Time) (Field, error)
	DeleteFieldInGroup(ctx context.Context, groupID int, key string) error
	ReorderFieldsInGroup(ctx context.Context, groupID int, keys []string) error
	MoveField(ctx context.Context, groupID int, key string, toGroup int) (Field, error)
	CreateField(ctx context.Context, f Field) (Field, error)
	AdoptType(ctx context.Context, key string) error
	AdoptGroup(ctx context.Context, key string) error
}

TypeStore persists the content type registry and its field definitions.

type Values added in v0.5.0

type Values map[string]any

Values holds a content item's scalar field values keyed by field key.

func ListedValues added in v0.11.0

func ListedValues(fields []Field, values Values) Values

ListedValues returns the shown values under the fields opted into the admin list.

func Shown added in v0.11.0

func Shown(fields []Field, values Values) Values

Shown returns the values with every key the conditions hide taken away, at any depth.

func (Values) Merge added in v0.5.0

func (v Values) Merge(patch Values) Values

Merge returns the stored values with the patch applied, where a nil value clears its key.

func (Values) Validate added in v0.5.0

func (v Values) Validate(fields []Field) error

Validate reports whether every value matches the kind its field declares and the bounds it carries.

func (Values) ValidateShape added in v0.11.0

func (v Values) ValidateShape(fields []Field) error

ValidateShape reports whether every value matches its field's kind, leaving the bounds alone.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL