Documentation
¶
Overview ¶
Package kinds is the site's content model as configuration: content kinds, entity kinds, tiers, restrictions and domain visibility policies. One Config drives storage, routes, media kinds, search and URLs (ContentKit #117).
Index ¶
- Constants
- Variables
- func ValidateAttributes(declared map[string]Attribute, values map[string]any) (map[string]any, error)
- type Attribute
- type Config
- type ContentFilter
- type ContentFilters
- type Domain
- type Download
- type GroupKind
- type GroupRef
- type Kind
- type Locked
- type Preview
- type UploadLimits
- type VersionRules
Constants ¶
const ( // DownloadPages is a zip of the version's pages (the media kind's // Publish.Download), the default of readers. DownloadPages = "pages" // DownloadOriginal is the version's video as uploaded (the upload its HLS // ladder encodes), the default of players. DownloadOriginal = "original" )
What a download serves.
const ( ShowDescription = "description" // the content's and versions' descriptions ShowCover = "cover" ShowGroups = "entities" ShowAttributes = "attributes" // the content's and versions' attributes ShowLength = "length" // versions' page counts, durations and segments ShowReactions = "reactions" // like and dislike counts; locked viewers may react ShowFavorites = "favorites" // favorite counts ShowViews = "views" // view counts ShowComments = "comments" // comments and their counts; locked viewers may comment )
Properties a Locked view may show.
Variables ¶
var DefaultLocked = Locked{Show: []string{ShowDescription, ShowCover, ShowGroups, ShowAttributes, ShowLength}}
DefaultLocked shows a kind's metadata and cover: no preview, counts or comments.
var ErrInvalid = errors.New("kinds: invalid config")
ErrInvalid is a Config that cannot be served.
var Shown = []string{ShowDescription, ShowCover, ShowGroups, ShowAttributes, ShowLength, ShowReactions, ShowFavorites, ShowViews, ShowComments}
Shown are the properties a Locked view may show.
Functions ¶
func ValidateAttributes ¶
func ValidateAttributes(declared map[string]Attribute, values map[string]any) (map[string]any, error)
ValidateAttributes checks values against the declared attributes and returns them normalized: ints as int64, times as RFC 3339 UTC. A nil value drops the attribute; an undeclared one or a value of the wrong type is ErrInvalid.
Types ¶
type Attribute ¶
type Attribute struct {
// Type is string, int, bool, enum or time.
Type string `json:"type" yaml:"type"`
Values []string `json:"values,omitempty" yaml:"values"`
Filterable bool `json:"filterable,omitempty" yaml:"filterable"`
Sortable bool `json:"sortable,omitempty" yaml:"sortable"`
}
Attribute is one declared per-kind field.
type Config ¶
type Config struct {
Languages []string `json:"languages" yaml:"languages"`
Tiers []string `json:"tiers,omitempty" yaml:"tiers"`
TokenClaims []string `json:"token_claims,omitempty" yaml:"token_claims"`
Restrictions []string `json:"restrictions,omitempty" yaml:"restrictions"`
ContentFilters ContentFilters `json:"content_filters,omitempty" yaml:"content_filters"`
Kinds map[string]Kind `json:"kinds" yaml:"kinds"`
GroupKinds map[string]GroupKind `json:"entity_kinds,omitempty" yaml:"group_kinds"`
}
Config is the application's content model.
func (Config) DomainFor ¶ added in v0.97.0
DomainFor returns the domain serving host, ignoring case and port; the first domain when none matches. Host is the request host, not an authority selector.
func (Config) Routes ¶
Routes maps every content kind and group kind with a route to it: the first path segment of its pages (contenturl.Routes).
func (*Config) UnmarshalYAML ¶ added in v0.97.0
UnmarshalYAML keeps the shared policy strict even inside permissively decoded app configuration. Retired per-content-kind domain blocks are rejected.
type ContentFilter ¶
type ContentFilter struct {
Group GroupRef `json:"entity" yaml:"entity"`
Visible bool `json:"visible" yaml:"visible"`
UserToggle *bool `json:"user_toggle,omitempty" yaml:"user_toggle,omitempty"`
}
ContentFilter defines this domain's visibility for one entity. A nil UserToggle allows reader overrides. Internal and required entities are never reader-toggleable, irrespective of UserToggle.
func (ContentFilter) Toggleable ¶ added in v0.97.0
func (f ContentFilter) Toggleable() bool
Toggleable reports whether this rule permits reader overrides. The caller must additionally exclude internal and domain-required entities.
type ContentFilters ¶ added in v0.103.0
type ContentFilters struct {
AppliesTo []string `json:"applies_to" yaml:"applies_to"`
Domains []Domain `json:"domains" yaml:"domains"`
}
ContentFilters is one app's shared entity-filter policy. Filters apply to every selected content kind; required entities are independently scoped.
func DecodeContentFilters ¶ added in v0.103.0
func DecodeContentFilters(data []byte) (ContentFilters, error)
DecodeContentFilters reads an isolated YAML or JSON policy block. Hosts can pass their root config's content_filters section directly without copying the policy model or weakening its strict unknown-field validation.
func (ContentFilters) Clone ¶ added in v0.103.0
func (c ContentFilters) Clone() ContentFilters
Clone gives an embedded engine its own immutable policy snapshot, including the optional bool pointers and the per-kind required-entity slices.
func (*ContentFilters) UnmarshalYAML ¶ added in v0.103.0
func (c *ContentFilters) UnmarshalYAML(data []byte) error
UnmarshalYAML remains strict when an app uses a permissive outer decoder.
type Domain ¶ added in v0.97.0
type Domain struct {
Name string `json:"name" yaml:"name"`
Hosts []string `json:"hosts" yaml:"hosts"`
RequireEntities map[string][]GroupRef `json:"require_entities,omitempty" yaml:"require_entities,omitempty"`
Filters []ContentFilter `json:"filters,omitempty" yaml:"filters,omitempty"`
}
Domain is an entrypoint matched by request host. The first domain is the default for unmatched hosts. Names belong to entities, never policy config.
type Download ¶ added in v0.88.0
type Download struct {
// Off: the kind's versions have no download.
Off bool `json:"off,omitempty" yaml:"off"`
// Serve is DownloadPages, DownloadOriginal or a private MP4 preset of the
// kind's media ("mp4-1080"); empty is the presentation's default.
Serve string `json:"serve,omitempty" yaml:"serve"`
}
Download is what a kind's version download serves. Whether a viewer may download, and which pages are marked, is the host's DownloadPolicy.
type GroupKind ¶
type GroupKind struct {
Route string `json:"route,omitempty" yaml:"route"`
// Ordered members carry positions (series, playlists, rails).
Ordered bool `json:"ordered,omitempty" yaml:"ordered"`
// Parent is the group kind a group may sit under (series under series).
Parent string `json:"parent,omitempty" yaml:"parent"`
// ScopedBy makes slugs unique within a group of that kind (character
// within series).
ScopedBy string `json:"scoped_by,omitempty" yaml:"scoped_by"`
// Owner is "site" (staff-managed) or "user" (channels, playlists): a
// signed-in person creates a user-owned group and owns it.
Owner string `json:"owner,omitempty" yaml:"owner"`
// MaxPerOwner caps the active groups of the kind one person owns; 0 is
// no cap. Staff are not capped.
MaxPerOwner int `json:"max_per_owner,omitempty" yaml:"max_per_owner"`
// Uploads limit what editors other than staff upload to a user-owned
// group's media.
Uploads UploadLimits `json:"uploads,omitzero" yaml:"uploads"`
// Sellable groups carry offers; their key unlocks every member.
Sellable bool `json:"sellable,omitempty" yaml:"sellable"`
// AuthScope groups name an AuthKit group whose permissions govern their
// content (OnlyDemo channels).
AuthScope bool `json:"auth_scope,omitempty" yaml:"auth_scope"`
// Windows lets memberships carry active_from/active_until (rails).
Windows bool `json:"windows,omitempty" yaml:"windows"`
// VersionLevel lets memberships target one version (voice actors).
VersionLevel bool `json:"version_level,omitempty" yaml:"version_level"`
// Roles are membership roles (publisher on an artist group).
Roles []string `json:"roles,omitempty" yaml:"roles"`
Attributes map[string]Attribute `json:"attributes,omitempty" yaml:"attributes"`
}
GroupKind is one kind of grouping: tag, artist, series, channel, rail, ...
type GroupRef ¶
type GroupRef struct {
Kind string `json:"kind" yaml:"kind"`
Slug string `json:"slug" yaml:"slug"`
}
GroupRef names an entity by kind and canonical slug.
type Kind ¶
type Kind struct {
// Route is the URL segment: /{lang}/{route}/{CODE}/{slug}.
Route string `json:"route" yaml:"route"`
// Presentation tells contentkit-ui how to show it: reader, player or post.
Presentation string `json:"presentation" yaml:"presentation"`
Versions VersionRules `json:"versions" yaml:"versions"`
// Segments enables ordered, individually released ranges (chapters).
Segments bool `json:"segments,omitempty" yaml:"segments"`
// Groups are the group kinds content of this kind may join.
Groups []string `json:"entities,omitempty" yaml:"groups"`
Attributes map[string]Attribute `json:"attributes,omitempty" yaml:"attributes"`
// Sort is the default list order.
Sort string `json:"sort,omitempty" yaml:"sort"`
// Locked is what a viewer who does not open its content sees of it;
// nil is DefaultLocked.
Locked *Locked `json:"locked,omitempty" yaml:"locked"`
// DraftTTL expires drafts that never went live this long after their
// creation: they are deleted, media included. Zero keeps them.
DraftTTL time.Duration `json:"draft_ttl,omitempty" yaml:"draft_ttl"`
// Download is what a version's download serves; nil serves its
// presentation's default (Download.Serves).
Download *Download `json:"download,omitempty" yaml:"download"`
}
Kind is one content kind: a gallery, a movie, a creator post, a blog post.
func (Kind) LockedView ¶ added in v0.88.0
LockedView is k's Locked, else DefaultLocked.
type Locked ¶ added in v0.88.0
type Locked struct {
Show []string `json:"show" yaml:"show"`
// Preview is the free part when its access rule names none; nil is none.
Preview *Preview `json:"preview,omitempty" yaml:"preview"`
}
Locked is what a viewer who does not open content (or a version) still sees of it: the properties Show names and the free part Preview names. Its id, code, path, title, languages, traits, owner, creators and paywall always show; its body and private media never do.
type Preview ¶ added in v0.86.0
type Preview struct {
Pages int `json:"pages,omitempty" yaml:"pages"`
Segments int `json:"segments,omitempty" yaml:"segments"`
}
Preview is the free part of locked content: its first Pages pages or first Segments segments (chapters).
type UploadLimits ¶
type UploadLimits struct {
// FilesPerHour and BytesPerDay limit each uploader.
FilesPerHour int `json:"files_per_hour,omitempty" yaml:"files_per_hour"`
BytesPerDay int64 `json:"bytes_per_day,omitempty" yaml:"bytes_per_day"`
// QuotaBytes caps the group's stored originals.
QuotaBytes int64 `json:"quota_bytes,omitempty" yaml:"quota_bytes"`
}
UploadLimits bound a user-owned group's uploads; zero fields are off.
type VersionRules ¶
type VersionRules struct {
// Languages is "one" (a version serves one language) or "many".
Languages string `json:"languages" yaml:"languages"`
// Traits are the declared version traits (colored, uncensored, ...).
Traits []string `json:"traits,omitempty" yaml:"traits"`
// Hidden kinds have exactly one version that clients never see.
Hidden bool `json:"hidden,omitempty" yaml:"hidden"`
}
VersionRules shape a kind's versions.