Help us shape the future of Go! Take the 2026 Go Developer Survey

content

package
v0.1.2 Latest Latest
Warning

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

Go to latest
Published: Nov 1, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package content stores multilingual content for modules. A module describes its content with two structs and a Spec; this package takes care of the tables, the languages, slugs, publication and which media the content uses.

  • Revisions keeps immutable revisions: save drafts, preview, publish, restore.
  • Collection keeps one row per item with a published flag and an order.

Fields (F) and translated text (T) are structs whose `db` tags name columns. The tables each store expects are listed on Revisions and Collection; content/testdata holds a complete example schema for every dialect.

Index

Constants

View Source
const MaxReviewNote = 500

MaxReviewNote is the longest note a reviewer can leave, in characters.

Variables

View Source
var (
	// ErrNotFound is db.ErrNotFound, so errors from either layer match.
	ErrNotFound = db.ErrNotFound
	// ErrInvalid is content the store cannot take as it is, such as an
	// unknown language, a language twice or a slug with other characters
	// than lowercase letters, digits and dashes. The error names the value.
	ErrInvalid = errors.New("invalid_content")
	// ErrIncomplete refuses to publish content whose translation in the
	// required language is missing or incomplete (see Spec.Complete); the
	// error names the language.
	ErrIncomplete = errors.New("content_translation_incomplete")
	// ErrDuplicateSlug is a slug that another item of the same instance
	// already has in that language; the error names the language and slug.
	ErrDuplicateSlug = errors.New("duplicate_slug")
	// ErrMediaMissing is content that refers to a file no longer in the
	// media library.
	ErrMediaMissing = errors.New("referenced_media_not_found")
	// ErrTooLong is returned by Spec.Check functions for a text over its
	// limit; the admin's editor explains it without a module message.
	ErrTooLong = errors.New("content_too_long")
)
View Source
var (
	// ErrNotApproved refuses to publish or schedule a revision that is not
	// approved while the instance's review workflow is on.
	ErrNotApproved = errors.New("revision_not_approved")
	// ErrReviewState refuses a review step the revision is not ready for,
	// such as approving a revision nobody submitted, or a rejection
	// without a note.
	ErrReviewState = errors.New("invalid_review_state")
)
View Source
var ErrSchedule = errors.New("invalid_schedule")

ErrSchedule is returned for a schedule that cannot be carried out.

Functions

func ReviewRequired

func ReviewRequired(ctx context.Context, instance string) bool

ReviewRequired reports whether ctx's policy (see WithReview) requires an approved revision before publishing in instance.

func Slug

func Slug(title string) string

Slug derives a URL slug from a title, for example "Café opens again!" becomes "cafe-opens-again": lowercase ASCII letters and digits joined by dashes, at most 80 characters, cut between words. Text without such letters, for example in another script, gives "".

func TooLong

func TooLong(limit int, values ...string) bool

TooLong reports whether one of the values is longer than limit characters. It counts characters, not bytes, as the admin's forms and the databases' VARCHAR columns do, so a text the form accepted in any script also passes a Spec.Check.

func UniqueSlug

func UniqueSlug(slug string, taken func(slug string) bool) string

UniqueSlug returns slug when taken does not report it as used, and otherwise the first of slug-2, slug-3, … that is free, for example to give a new item a slug made with Slug that no other item has.

func WithReview

func WithReview(ctx context.Context, policy ReviewPolicy) context.Context

WithReview returns ctx in which publishing follows policy: the admin sets it for signed-in requests and the App's scheduler for its runs. Without a policy, as in seeds, imports and tests, no review is needed.

Types

type Collection

type Collection[F, T any] struct {
	// contains filtered or unexported fields
}

Collection stores one row per item with a published flag and an order. Tables, for Table "x":

x             (id, instance, published, position, created_at, created_by,
               updated_at, updated_by, deleted_at, deleted_by, <fields>)
x_translation (item_id, locale, <text>)

Delete moves an item to the trash (see Revisions). A unique index on a field, such as a slug, should leave deleted rows out: a partial index (WHERE deleted_at IS NULL) in SQLite and Postgres, a generated column in MySQL; content/testdata shows both.

func NewCollection

func NewCollection[F, T any](database *db.DB, spec Spec[F, T]) (*Collection[F, T], error)

NewCollection returns a Collection for spec on database. It checks that spec names a table, a Complete function and, with a SlugColumn, a text field of that name, so a mistake fails at start rather than in the first query.

func (*Collection[F, T]) Delete

func (c *Collection[F, T]) Delete(ctx context.Context, instance, id string) error

Delete moves the item to the trash. It keeps its place, its publication and the media it uses, so Undelete brings it back as it was.

func (*Collection[F, T]) Get

func (c *Collection[F, T]) Get(ctx context.Context, instance, id string) (Item[F, T], error)

Get returns one item of instance with every translation, published or not, for the admin. It returns ErrNotFound for an item that does not exist or is in the trash.

func (*Collection[F, T]) In

func (c *Collection[F, T]) In(instance string) Store[F, T]

In binds the collection to an instance: saving changes the item directly, publishing sets a flag and items can be moved.

func (*Collection[F, T]) List

func (c *Collection[F, T]) List(ctx context.Context, instance string) ([]Item[F, T], error)

List returns all items in their order.

func (*Collection[F, T]) ListPublished

func (c *Collection[F, T]) ListPublished(ctx context.Context, instance, locale string) ([]Item[F, T], error)

ListPublished returns published items that are complete in locale, in order.

func (*Collection[F, T]) Move

func (c *Collection[F, T]) Move(ctx context.Context, instance, id string, position int) error

Move puts an item at position; other items keep their relative order.

func (*Collection[F, T]) Published

func (c *Collection[F, T]) Published(ctx context.Context, instance, id, locale string) (Item[F, T], error)

Published returns one published item if it is complete in locale.

func (*Collection[F, T]) PublishedBySlug

func (c *Collection[F, T]) PublishedBySlug(ctx context.Context, instance, locale, slug string) (Item[F, T], error)

PublishedBySlug finds a published item by its translated slug.

func (*Collection[F, T]) Purge

func (c *Collection[F, T]) Purge(ctx context.Context, instance, id string) error

Purge removes an item in the trash for good.

func (*Collection[F, T]) Recent

func (c *Collection[F, T]) Recent(ctx context.Context, instance string, limit int) ([]Item[F, T], error)

Recent returns at most limit items, the most recently changed first.

func (*Collection[F, T]) Save

func (c *Collection[F, T]) Save(ctx context.Context, instance string, draft Draft[F, T]) (Item[F, T], error)

Save creates or replaces an item. New items (empty or unknown ID) are added at the end, unpublished.

func (*Collection[F, T]) SetPublished

func (c *Collection[F, T]) SetPublished(ctx context.Context, instance, id string, published bool, required string) error

SetPublished shows or hides an item. Publishing requires the required locale.

func (*Collection[F, T]) Spec

func (c *Collection[F, T]) Spec() Spec[F, T]

Spec returns the description the Collection was made with, for code that needs its rules, such as Available.

func (*Collection[F, T]) Trashed

func (c *Collection[F, T]) Trashed(ctx context.Context, instance string) ([]Item[F, T], error)

Trashed returns the items in the trash, most recently deleted first.

func (*Collection[F, T]) Undelete

func (c *Collection[F, T]) Undelete(ctx context.Context, instance, id string) error

Undelete brings an item back from the trash. An item whose slug another item took meanwhile stays in the trash with ErrDuplicateSlug.

type Draft

type Draft[F, T any] struct {
	// ID is empty for new content.
	ID string
	// Fields are the language-independent values.
	Fields F
	// Translations are the texts per language; languages left out have no
	// text.
	Translations []Translation[T]
	// Author is the user ID; empty for system changes. Revisions only.
	Author string
	// Note is an optional change note. Revisions only.
	Note string
}

Draft is what an editor submits: a new revision, or the new item state.

type IDs

type IDs []string

IDs is a small list of references stored in one text column, for example a post's categories. Use a separate table when the list can grow large.

func (IDs) Has

func (ids IDs) Has(id string) bool

Has reports whether id is in the list.

func (*IDs) Scan

func (ids *IDs) Scan(value any) error

Scan implements sql.Scanner, reading the comma separated column back; an empty or NULL column is no IDs.

func (IDs) Value

func (ids IDs) Value() (driver.Value, error)

Value implements driver.Valuer: the IDs are stored comma separated.

type Item

type Item[F, T any] struct {
	ID           string
	Instance     string
	Fields       F
	Translations []Translation[T]
	CreatedAt    time.Time
	UpdatedAt    time.Time
	// CreatedBy and UpdatedBy are the IDs of the users who made the item and
	// changed it last; empty for visitors and the system (see db.Actor).
	CreatedBy string
	UpdatedBy string
	// DeletedAt is when the item went to the trash, by DeletedBy; nil for
	// live items. Only Trashed returns deleted items.
	DeletedAt *time.Time
	DeletedBy string

	// Published is true when the item is visible. For Revisions this means some
	// revision is published, not necessarily the one in this Item.
	Published bool

	// Collection only.
	Position int

	// Revisions only.
	Revision        Revision
	PublishedID     string
	PublishedNumber int
	// Schedule is the item's planned publication change, if any.
	Schedule Schedule
}

Item is one piece of content. For Revisions it holds one specific revision.

func (Item[F, T]) IsPublishedRevision

func (i Item[F, T]) IsPublishedRevision() bool

IsPublishedRevision reports whether this Item holds the published revision.

func (Item[F, T]) Text

func (i Item[F, T]) Text(locale string) (T, bool)

Text returns the translation for locale, if one was written.

func (Item[F, T]) WithText

func (i Item[F, T]) WithText(locale string, text T) []Translation[T]

WithText returns the translations with locale set to text, keeping the others.

type Mover

type Mover interface {
	Move(ctx context.Context, id string, position int) error
}

Mover is implemented by stores whose items have an order (collections).

type Planner

type Planner[F, T any] interface {
	Planned(ctx context.Context) ([]Item[F, T], error)
}

Planner is implemented by stores whose publication can be planned: it lists the items with a planned change, the earliest first.

type Publisher

type Publisher struct {
	// Publish publishes revisionID of item id, which must be complete in
	// the required language.
	Publish func(ctx context.Context, id, revisionID, required string) error
	// Unpublish takes item id off the website.
	Unpublish func(ctx context.Context, id string) error
}

Publisher makes the scheduled changes of RunDue. Owners whose publication has side effects, such as the page tree's routes, give their own; nil functions use the store's Publish and Unpublish.

The functions must not clear the item's plan themselves: RunDue already cleared the step it carries out, and the rest (an unpublication after a publication) must stay. Calling the store's Publish and Unpublish with the ctx they receive is safe: it carries a marker that keeps them from cancelling the plan as they do when an editor publishes by hand.

type Review

type Review struct {
	State       ReviewState
	SubmittedBy string
	SubmittedAt time.Time
	ReviewedBy  string
	ReviewedAt  time.Time
	// Note is the reviewer's comment, required when rejecting.
	Note string
}

Review is the review state of a revision. SubmittedBy and ReviewedBy are user IDs; empty, like the times, until that step happened.

type ReviewPolicy

type ReviewPolicy func(ctx context.Context, instance string) bool

ReviewPolicy reports whether publishing in an instance needs an approved revision. Sites usually decide it per admin section in their settings; the sections of revisioned content are named after their instance.

type ReviewState

type ReviewState string

ReviewState is where a revision is in the review workflow.

const (
	// ReviewDraft is a revision nobody asked to review; every revision
	// starts as one.
	ReviewDraft ReviewState = "draft"
	// ReviewPending is a revision submitted for review.
	ReviewPending ReviewState = "review"
	// ReviewApproved is a revision a reviewer approved; it can be published.
	ReviewApproved ReviewState = "approved"
	// ReviewRejected is a revision a reviewer sent back, with a note why.
	ReviewRejected ReviewState = "rejected"
)

type Reviewing

type Reviewing[F, T any] interface {
	// ReviewRequired reports whether publishing needs an approved revision
	// under ctx's policy (see WithReview).
	ReviewRequired(ctx context.Context) bool
	// Submit asks for a review of a revision.
	Submit(ctx context.Context, id, revision string) error
	// Approve and Reject decide on a submitted revision.
	Approve(ctx context.Context, id, revision, note string) error
	Reject(ctx context.Context, id, revision, note string) error
	// InReview lists at most limit revisions waiting for review.
	InReview(ctx context.Context, limit int) ([]Item[F, T], error)
}

Reviewing is a store whose revisions can be reviewed; Revisions.In returns one.

type Revision

type Revision struct {
	ID string
	// Number counts the item's revisions from 1, for people.
	Number int
	// Author is the ID of the user who saved it; empty for system changes.
	Author    string
	CreatedAt time.Time
	// Note is the change note the author gave, if any.
	Note string
	// Review is the revision's state in the optional review workflow (see
	// WithReview).
	Review Review
}

Revision is the metadata of one immutable revision.

type Revisions

type Revisions[F, T any] struct {
	// contains filtered or unexported fields
}

Revisions stores content as immutable revisions. Tables, for Table "x":

x             (id, instance, published_revision_id, scheduled_revision_id,
               publish_at, unpublish_at, created_at, created_by,
               updated_at, updated_by, deleted_at, deleted_by)
x_revision    (id, entity_id, revision_no, author, created_at, note,
               review_state, submitted_at, submitted_by,
               reviewed_at, reviewed_by, review_note, <fields>)
x_translation (revision_id, locale, <text>)

The item row keeps the audit columns (see db.Actor); a revision row is never changed except for its review state (see Review), and its author and created_at say who made it and when.

Delete moves an item to the trash: it disappears from every list and lookup until Undelete brings it back or Purge removes it for good.

func NewRevisions

func NewRevisions[F, T any](database *db.DB, spec Spec[F, T]) (*Revisions[F, T], error)

NewRevisions returns a Revisions store for spec on database. It checks that spec names a table, a Complete function and, with a SlugColumn, a text field of that name, so a mistake fails at start rather than in the first query.

func (*Revisions[F, T]) AllPublished

func (r *Revisions[F, T]) AllPublished(ctx context.Context, instance string) ([]Item[F, T], error)

AllPublished loads the published revision of every item, in any language.

func (*Revisions[F, T]) Approve

func (r *Revisions[F, T]) Approve(ctx context.Context, instance, id, revisionID, note string) error

Approve marks a submitted revision as approved by the user in ctx, with an optional note. Publishing is a separate step.

func (*Revisions[F, T]) Delete

func (r *Revisions[F, T]) Delete(ctx context.Context, instance, id string) error

Delete moves the item to the trash. It keeps its revisions, its publication and the media it uses, so Undelete brings it back as it was; planned publication changes are cancelled.

func (*Revisions[F, T]) Find

func (r *Revisions[F, T]) Find(ctx context.Context, instance, revisionID string) (Item[F, T], error)

Find loads a revision by its ID alone, for a preview that names only the revision; the item must be live and of instance.

func (*Revisions[F, T]) History

func (r *Revisions[F, T]) History(ctx context.Context, instance, id string) ([]Revision, error)

History lists revision metadata, newest first.

func (*Revisions[F, T]) In

func (r *Revisions[F, T]) In(instance string) Store[F, T]

In binds the store to an instance: saving creates drafts, publishing is explicit and revisions can be restored. The store implements Scheduling and Reviewing.

func (*Revisions[F, T]) InReview

func (r *Revisions[F, T]) InReview(ctx context.Context, instance string, limit int) ([]Item[F, T], error)

InReview loads at most limit revisions waiting for review, of live items, the longest waiting first.

func (*Revisions[F, T]) Latest

func (r *Revisions[F, T]) Latest(ctx context.Context, instance, id string) (Item[F, T], error)

Latest loads the newest revision, published or not.

func (*Revisions[F, T]) ListLatest

func (r *Revisions[F, T]) ListLatest(ctx context.Context, instance string) ([]Item[F, T], error)

ListLatest loads the newest revision of every item, newest items first.

func (*Revisions[F, T]) ListPublished

func (r *Revisions[F, T]) ListPublished(ctx context.Context, instance, locale string) ([]Item[F, T], error)

ListPublished loads published content that is complete in locale, newest first.

func (*Revisions[F, T]) Outline

func (r *Revisions[F, T]) Outline(ctx context.Context, instance string, texts ...string) ([]Item[F, T], error)

Outline is ListLatest with only the named texts of the translations, by their `db` names such as "slug" and "title"; the other texts stay empty. Code that only needs the shape of the content, such as a tree with titles and slugs, uses it to leave long texts such as bodies unread. An unknown name is an error.

func (*Revisions[F, T]) Planned

func (r *Revisions[F, T]) Planned(ctx context.Context, instance string) ([]Item[F, T], error)

Planned loads the latest revision of the items with a planned publication change, the earliest change first.

func (*Revisions[F, T]) PreviewBySlug

func (r *Revisions[F, T]) PreviewBySlug(ctx context.Context, instance, locale, slug, revisionID string) (Item[F, T], error)

PreviewBySlug is PublishedBySlug for an address an editor may preview (see frontend.PreviewParam): with a revision ID it returns that revision when it belongs to the content at slug, that is the published item with that slug or, when none is published there, an item whose revision has that slug in locale, such as one never published. For every other revision, and without one, it returns what PublishedBySlug returns, so a preview never shows other content at an address.

func (*Revisions[F, T]) Publish

func (r *Revisions[F, T]) Publish(ctx context.Context, instance, id, revisionID, required string) error

Publish makes a revision public. required is the locale that must be complete, usually the site's default locale; published slugs must be unique per locale. It cancels the item's planned publication changes (see Schedule). While the instance's review workflow is on (see WithReview), only an approved revision is published; others are ErrNotApproved.

func (*Revisions[F, T]) Published

func (r *Revisions[F, T]) Published(ctx context.Context, instance, id, locale string) (Item[F, T], error)

Published loads the published revision if it is complete in locale.

func (*Revisions[F, T]) PublishedBySlug

func (r *Revisions[F, T]) PublishedBySlug(ctx context.Context, instance, locale, slug string) (Item[F, T], error)

PublishedBySlug finds published content by its translated slug.

func (*Revisions[F, T]) Purge

func (r *Revisions[F, T]) Purge(ctx context.Context, instance, id string) error

Purge removes an item in the trash for good, with all its revisions.

func (*Revisions[F, T]) Recent

func (r *Revisions[F, T]) Recent(ctx context.Context, instance string, limit int) ([]Item[F, T], error)

Recent loads the latest revision of at most limit items, the most recently changed first, for overviews such as the admin dashboard.

func (*Revisions[F, T]) Reject

func (r *Revisions[F, T]) Reject(ctx context.Context, instance, id, revisionID, note string) error

Reject sends a submitted revision back; note says why and is required.

func (*Revisions[F, T]) Restore

func (r *Revisions[F, T]) Restore(ctx context.Context, instance, id, revisionID, author string) (Item[F, T], error)

Restore copies an old revision into a new latest revision. It does not publish.

func (*Revisions[F, T]) Reviews

func (r *Revisions[F, T]) Reviews(instance string) Reviewing[F, T]

Reviews is the review workflow of an instance (see Reviewing), for stores of their own that wrap Revisions, such as the page tree's.

func (*Revisions[F, T]) Revision

func (r *Revisions[F, T]) Revision(ctx context.Context, instance, id, revisionID string) (Item[F, T], error)

Revision loads one specific revision.

func (*Revisions[F, T]) RunDue

func (r *Revisions[F, T]) RunDue(
	ctx context.Context,
	instance string,
	now time.Time,
	required string,
	publisher Publisher,
) (int, error)

RunDue carries out the plans of instance that are due at now, earliest first. It returns the number of changes made; failed changes are joined in the error and do not stop the others.

func (*Revisions[F, T]) Save

func (r *Revisions[F, T]) Save(ctx context.Context, instance string, draft Draft[F, T]) (Item[F, T], error)

Save stores a new revision. An empty or unknown draft ID creates new content.

func (*Revisions[F, T]) Schedule

func (r *Revisions[F, T]) Schedule(ctx context.Context, instance, id string, schedule Schedule, required string) error

Schedule plans the publication of a revision and/or the unpublication of an item. The revision must belong to the item, be complete in required and, while the review workflow is on, approved (see WithReview); unpublishing must come after publishing. Times in the past are carried out on the scheduler's next run.

func (*Revisions[F, T]) Scheduler

func (r *Revisions[F, T]) Scheduler(instance string) Scheduler

Scheduler carries out the planned publication changes of an instance, for the App's scheduler (see webthings.Parts.Scheduled).

func (*Revisions[F, T]) Spec

func (r *Revisions[F, T]) Spec() Spec[F, T]

Spec returns the description the store was made with, for code that needs its rules, such as Available.

func (*Revisions[F, T]) Submit

func (r *Revisions[F, T]) Submit(ctx context.Context, instance, id, revisionID string) error

Submit asks for a review of a draft or rejected revision; the user in ctx (see db.Actor) is the one who asked. An earlier revision of the item that still waits for review goes back to draft: the newest submission is the one to review. The published revision cannot be submitted.

func (*Revisions[F, T]) Trashed

func (r *Revisions[F, T]) Trashed(ctx context.Context, instance string) ([]Item[F, T], error)

Trashed loads the latest revision of every item in the trash, most recently deleted first.

func (*Revisions[F, T]) Undelete

func (r *Revisions[F, T]) Undelete(ctx context.Context, instance, id string) error

Undelete brings an item back from the trash. A published item whose slug another published item took meanwhile stays in the trash with ErrDuplicateSlug.

func (*Revisions[F, T]) Unpublish

func (r *Revisions[F, T]) Unpublish(ctx context.Context, instance, id string) error

Unpublish takes an item offline and cancels its planned publication changes.

func (*Revisions[F, T]) Unschedule

func (r *Revisions[F, T]) Unschedule(ctx context.Context, instance, id string) error

Unschedule cancels the plan of an item.

type Schedule

type Schedule struct {
	// RevisionID is published at PublishAt; both are empty when only
	// unpublishing is planned.
	RevisionID string
	PublishAt  time.Time
	// UnpublishAt takes the item offline; zero when not planned.
	UnpublishAt time.Time
}

Schedule is the planned publication change of one item.

func (Schedule) IsZero

func (s Schedule) IsZero() bool

IsZero reports whether nothing is planned.

type Scheduler

type Scheduler interface {
	// RunDue publishes and unpublishes what is due at now and returns how many
	// changes it made. Published revisions must be complete in required.
	RunDue(ctx context.Context, now time.Time, required string) (int, error)
}

Scheduler carries out planned publication changes.

type Scheduling

type Scheduling interface {
	Scheduler
	// Schedule replaces the plan of an item. required is the locale a
	// published revision must be complete in.
	Schedule(ctx context.Context, id string, schedule Schedule, required string) error
	// Unschedule cancels the plan of an item.
	Unschedule(ctx context.Context, id string) error
}

Scheduling is a store whose publication can be planned; Revisions.In returns one.

type Spec

type Spec[F, T any] struct {
	// Table is the base table name, for example "wt_publishing_post".
	Table string
	// Complete reports whether a translation can be shown publicly.
	Complete func(T) bool
	// SlugColumn names T's slug column. Empty means the content has no detail URLs.
	SlugColumn string
	// Check validates module rules after the kit normalized locales and slugs.
	Check func(fields F, translations []Translation[T]) error
	// Media lists referenced media asset IDs. They cannot be deleted while used.
	Media func(fields F, translations []Translation[T]) []string
	// Deletable refuses moving an item to the trash with an error, for
	// example while live items of another type still refer to it. Nil
	// allows every delete.
	Deletable func(ctx context.Context, id string) error
	// Changed, when set, is called after every committed write that may
	// change what visitors see: publishing, unpublishing, moving to the
	// trash and back and, for a Collection, saving and moving an item.
	// Modules set it to webthings.Env.Changed, so the output cache renders
	// its pages again also after a write made from Go, such as an import,
	// a seed or a background job.
	Changed func()
}

Spec describes one content type.

func (Spec[F, T]) Available

func (s Spec[F, T]) Available(item Item[F, T], locale string) bool

Available reports whether item has a complete translation for locale.

type Store

type Store[F, T any] interface {
	// Spec returns the description of the content.
	Spec() Spec[F, T]
	// List returns every item outside the trash, published or not, in the
	// store's order.
	List(ctx context.Context) ([]Item[F, T], error)
	// Load returns the latest state, or a specific revision when revision is set.
	Load(ctx context.Context, id, revision string) (Item[F, T], error)
	// Save stores draft: a new revision, or the new state of the item. It
	// does not publish.
	Save(ctx context.Context, draft Draft[F, T]) (Item[F, T], error)
	// Delete moves the item to the trash.
	Delete(ctx context.Context, id string) error
	// Trashed lists the items in the trash, most recently deleted first.
	Trashed(ctx context.Context) ([]Item[F, T], error)
	// Undelete brings an item back from the trash; ErrDuplicateSlug when
	// another item took its slug meanwhile.
	Undelete(ctx context.Context, id string) error
	// Purge removes an item in the trash for good.
	Purge(ctx context.Context, id string) error
	// Recent returns at most limit items, the most recently changed first.
	Recent(ctx context.Context, limit int) ([]Item[F, T], error)
	// Publish makes the item (or the given revision) public; locale must be complete.
	Publish(ctx context.Context, id, revision, locale string) error
	// Unpublish takes the item off the website; it stays in the admin.
	Unpublish(ctx context.Context, id string) error
	// Revisioned reports whether History and Restore are available.
	Revisioned() bool
	// History lists the item's revisions, newest first; nil when the store
	// keeps none.
	History(ctx context.Context, id string) ([]Revision, error)
	// Restore copies an old revision into a new latest revision by author.
	// It does not publish.
	Restore(ctx context.Context, id, revision, author string) (Item[F, T], error)
}

Store is the content of one instance: everything an editor, an import or a seed needs. Get one with Revisions.In or Collection.In.

type Translation

type Translation[T any] struct {
	// Locale is the language code, such as "nl"; stores normalize it (see
	// locales.Normalize).
	Locale string
	// Text is the translated text, the T of the Spec.
	Text T
}

Translation is the text of an item in one language, such as the title and body of a post in Dutch.

func SetText

func SetText[T any](translations []Translation[T], locale string, text T) []Translation[T]

SetText returns translations with locale set to text, keeping the others.

Jump to

Keyboard shortcuts

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