Documentation
¶
Overview ¶
Package urlpattern implements the URL pattern mini-language used for per-schema public routing: parsing, rendering an entity to a path, matching a path back to its variables, and a Router that resolves a path to the schemas that may serve it.
A pattern is a slash-separated path whose segments are either literals or one of the whole-segment tokens {parent}, {slug}, {path}, {year}, {month} and {day}:
/post/{slug}
/blog/{slug}
/docs/{parent}/{slug}
/{year}/{month}/{slug}
/{path}
The last segment is either {slug} or {path}, exactly one of them. {path} is the entity's whole ancestor chain of slugs plus its own, joined by '/' (services/seo/local), so it spans one to MaxPathDepth URL segments. {parent} is optional at render and match time: when the parent is empty its segment is omitted (it cannot be combined with {path}). {year} ("2024"), {month} ("05") and {day} ("09") are the entity's publication date.
Locale. Content carries a locale (a BCP 47 tag) but patterns have no language token: the default locale is never in the path, and the public site serves only entities whose locale equals the site language. A second locale would need: a language path token or prefix in a pattern, Resolve returning the locale of the match, a per-locale public filter in place of the exact site language match, hreflang alternates, per-locale sitemaps and feeds, translation links between entities, and an admin language switcher. None of this is built.
The package is pure (no I/O) so it can be unit tested exhaustively.
Index ¶
- Constants
- Variables
- func Render(p *Pattern, v Vars) (string, error)
- func SplitPath(path string) []string
- type Candidate
- type Override
- type Pattern
- type Router
- func (r *Router) CanonicalSchema(schemaSlug string) (string, bool)
- func (r *Router) Lookup(schemaSlug string, attrs map[string]string) (Target, bool)
- func (r *Router) Resolve(path string) []Candidate
- func (r *Router) SchemaSlugs(schemaSlug string) []string
- func (r *Router) URLFor(schemaSlug string, attrs map[string]string, v Vars) (string, bool, error)
- type SchemaRoute
- type Segment
- type Target
- type Token
- type Vars
Constants ¶
const MaxPathDepth = 8
MaxPathDepth caps the segments a {path} value may have (ancestors plus the entity), so a parent cycle or a hostile URL can never grow without bound.
Variables ¶
var ErrInvalidPattern = errors.New("invalid url pattern")
ErrInvalidPattern is wrapped by every Parse failure.
var ErrMissingVar = errors.New("missing url variable")
ErrMissingVar is returned by Render when a required variable is empty.
Functions ¶
Types ¶
type Candidate ¶
type Candidate struct {
// SchemaSlug is the schema's own slug; SchemaSlugs is the slug plus its
// aliases, i.e. every schema slug whose rows may be served here.
SchemaSlug string
SchemaSlugs []string
Pattern *Pattern
Vars Vars
// Override is non-nil when the match came from an override pattern: the
// caller must verify the entity's attribute equals Override.Equals.
Override *Override
}
Candidate is one way a request path can be served.
type Override ¶
Override swaps the pattern for entities whose attribute Attribute equals Equals. SitemapGroup optionally names a different sitemap child.
type Pattern ¶
type Pattern struct {
// contains filtered or unexported fields
}
Pattern is a parsed URL pattern.
func (*Pattern) FirstLiteral ¶
FirstLiteral returns the first path segment when it is a literal (for example "post" for /post/{slug}), or "" when the pattern starts with a token.
func (*Pattern) LiteralCount ¶
LiteralCount is the number of literal segments (higher = more specific).
func (*Pattern) TokenCount ¶
TokenCount is the number of token segments.
type Router ¶
type Router struct {
// contains filtered or unexported fields
}
Router resolves paths to candidate schemas and entities to URLs. It is immutable after NewRouter and safe for concurrent use.
func NewRouter ¶
func NewRouter(routes []SchemaRoute) (*Router, error)
NewRouter parses every route. It fails on the first invalid pattern.
func (*Router) CanonicalSchema ¶
CanonicalSchema maps a schema slug or alias to the owning schema's own slug.
func (*Router) Lookup ¶
Lookup returns the pattern for an entity of schemaSlug (own slug or alias). attrs are the entity's attributes flattened to strings; the first matching override wins.
func (*Router) Resolve ¶
Resolve returns every candidate whose pattern matches path, most specific first (more literal segments, then fewer tokens, then schema slug order).
func (*Router) SchemaSlugs ¶
SchemaSlugs returns the schema's own slug plus aliases for any known slug.
type SchemaRoute ¶
type SchemaRoute struct {
SchemaSlug string
Aliases []string
Pattern string
SitemapGroup string
Overrides []Override
}
SchemaRoute describes how one schema is addressed. Pattern is raw pattern text; Aliases are extra schema slugs resolving to this schema.
type Target ¶
type Target struct {
Pattern *Pattern
SitemapGroup string
// Override is non-nil when an override (not the schema's base pattern) applies.
Override *Override
}
Target is the pattern chosen for one entity.
type Vars ¶
type Vars struct {
Slug string
Parent string
// Path is the slash-joined slug chain ending with Slug ("a/b/slug").
// Render falls back to Slug when it is empty.
Path string
// Year, Month and Day are zero-padded ("2024", "05", "09").
Year, Month, Day string
}
Vars carries the values substituted into / extracted from a pattern.