Documentation
¶
Overview ¶
Package contenturl gives content uniform URLs, /{lang}/{route}/{CODE}[/{slug}]: the page's language (every page has one, the default included), a short random code ContentKit assigns once per content record (unique per tenant across every kind), a decorative slug, and the host's route for the content kind. The server reads only the code; any other spelling of the path redirects to the canonical one. ?v= selects a version (VersionParam).
Store registers codes and resolves them (and legacy aliases); Router maps content kinds to the host's routes, decides canonical redirects and serves a JSON lookup. Taxonomy nodes and posts are registered by ContentKit itself; hosts Put their own content.
Index ¶
- Constants
- Variables
- func AcceptLanguage(languages []string, header string) string
- func Slugify(title string) string
- type AliasKey
- type AliasLookup
- type AliasMatch
- type AliasResult
- type AliasResults
- type Code
- type Decision
- type Link
- type Parsed
- type Resolved
- type RouterOptions
- type Routes
- type VersionCode
- type VersionKey
- type Visibility
Constants ¶
const (
AliasFound = "found"
)
const (
AliasGone = "gone" // its content was removed
)
const (
AliasNotFound = "not_found" // unknown, or hidden from the request's visitor
)
const Alphabet = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"
Alphabet is Crockford base32: digits and uppercase letters without I, L, O, U.
const CodeLength = 9
CodeLength is the length of a content code.
const MaxAliases = 100
MaxAliases bounds an AliasLookup.
const VersionCodeLength = 4
VersionCodeLength is the length of a version code.
const VersionParam = "v"
VersionParam is the query parameter that selects a version on its content's page: /{lang}/{route}/{CODE}/{slug}?v={version code}. A page without it, or whose code names no live version, shows the language's default edition.
Variables ¶
var (
ErrInvalid = codes.ErrInvalid
)
var (
ErrInvalidCode = fmt.Errorf("%w: not a content code", codes.ErrInvalid)
)
Functions ¶
func AcceptLanguage ¶ added in v0.86.0
AcceptLanguage is the first of languages an Accept-Language header names, as a tag or a tag's primary subtag; "" when it names none.
Types ¶
type AliasKey ¶ added in v0.83.0
type AliasKey struct {
Source string `json:"source"`
Kind string `json:"kind"`
Key string `json:"key"`
}
AliasKey names another system's identifier: the system (an import batch's source), the identifier's space and the identifier.
type AliasLookup ¶ added in v0.83.0
type AliasLookup struct {
Aliases []AliasKey `json:"aliases"`
}
AliasLookup is legacy identifiers to resolve, at most MaxAliases.
type AliasMatch ¶
AliasMatch is what an alias resolves to.
type AliasResult ¶ added in v0.83.0
type AliasResult struct {
AliasKey
// Status is found, not_found or gone.
Status string `json:"status"`
// Resolved is a found alias's link and canonical path.
Resolved *Resolved `json:"resolved,omitempty"`
// Locator is a found alias's position inside its content, such as a page.
Locator string `json:"locator,omitempty"`
}
AliasResult is what one alias resolves to.
type AliasResults ¶ added in v0.83.0
type AliasResults struct {
Aliases []AliasResult `json:"aliases"`
}
AliasResults answers an AliasLookup in its order.
type Code ¶
type Code string
Code is a content code in canonical form: nine characters of Alphabet, at least one a letter, so no code reads as a numeric id.
type Decision ¶
type Decision struct {
// Matched: the request names visible, routed content. When neither
// Matched nor Gone, the host serves the request as it would without the
// router (usually its 404).
Matched bool
// Gone: the request names routed content the host removed (410).
Gone bool
// Redirect: the path is not canonical; answer 301 to Location.
Redirect bool
// Private: matched only for this viewer (Preview); never cache or index it.
Private bool
Link Link
Language string
Path string // the canonical path
Location string // Path plus the request's query
}
Decision is the canonical verdict on a request.
type Link ¶
type Link struct {
contentref.ContentRef
Code Code `json:"code"`
Slug string `json:"slug"`
Slugs map[string]string `json:"slugs,omitempty"`
}
Link is what a code resolves to: the content, its canonical code and slugs. After a merge the content and code are the surviving record's.
type Parsed ¶
type Parsed struct {
Language string // "" when unprefixed (an old link: it redirects)
Route string
Code Code // canonical form
RawCode string // as written
Slug string // decorative segments as written, "/"-joined; "" when absent
}
Parsed is a content path split into its parts.
func ParsePath ¶
ParsePath splits [/{language}]/{route}/{code}[/{decorative...}][/] where route is one of routes' values and language one of languages; a path without the language, or with stale or extra decorative segments, is still read, for its redirect. ok is false for any other path, including an invalid code.
type Resolved ¶
type Resolved struct {
Link
Path string `json:"path"`
// VersionID is the live version ?v= names; "" when it names none, and the
// page shows its language's default edition.
VersionID string `json:"version_id,omitempty"`
}
Resolved is Handler's response: the link and its canonical path ("" when the kind has no route).
type RouterOptions ¶
type RouterOptions struct {
// Routes maps content kinds to the host's routes. Required.
Routes Routes
// Languages are the site's languages, its default first. Required: every
// content page is under one (/{lang}/{route}/...), which picks its slug;
// a request without one redirects to the language Accept-Language names,
// else the default.
Languages []string
// BaseURL ("https://example.com") makes Middleware send the canonical URL
// as a `Link: <url>; rel="canonical"` header. Empty: no header.
BaseURL string
// Visibility is the host's verdict on each resolved link, in order
// (drafts, removed content, viewer restrictions). nil: every registered
// code is Visible.
Visibility func(r *http.Request, links []Link) ([]Visibility, error)
// Gone answers requests for Gone content. nil: a plain 410.
Gone http.Handler
// Logger receives resolution failures (5xx). nil: slog.Default().
Logger *slog.Logger
}
RouterOptions configures a Router.
type Routes ¶
Routes maps a content kind to the host's route: the first path segment of its pages ("video" -> "watch", "gallery" -> "g"). Several kinds may share a route; a kind without one has no URL.
type VersionCode ¶ added in v0.86.0
type VersionCode string
VersionCode is a version's code in canonical form: four characters of Alphabet, at least one a letter, unique within its content and fixed for the version's life.
func (VersionCode) String ¶ added in v0.86.0
func (c VersionCode) String() string
type VersionKey ¶ added in v0.86.0
type VersionKey struct {
ContentID string
Code VersionCode
}
VersionKey names a version by its content and version code.
type Visibility ¶
type Visibility int
Visibility is the host's verdict on resolved content for one request. The zero value is Hidden, so an unset verdict fails closed.
const ( // Hidden content answers like an unknown code (the host's 404): no // redirect, so nothing about it (its slug) leaks. Hidden Visibility = iota // Visible content is served and canonicalized. Visible // Gone content was removed for good: 410, no redirect. Gone // Preview content is served only to the requesting editor (a draft they // may edit): resolved like Visible, never cached or indexed. Preview )