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

urlpattern

package
v1.0.2 Latest Latest
Warning

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

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

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

View Source
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

View Source
var ErrInvalidPattern = errors.New("invalid url pattern")

ErrInvalidPattern is wrapped by every Parse failure.

View Source
var ErrMissingVar = errors.New("missing url variable")

ErrMissingVar is returned by Render when a required variable is empty.

Functions

func Render

func Render(p *Pattern, v Vars) (string, error)

Render substitutes vars into the pattern. {slug} (or {path}) is required; an empty {parent} omits its segment. Values may not contain '/', except a {path} value, whose segments must be non-empty and at most MaxPathDepth.

func SplitPath

func SplitPath(path string) []string

SplitPath returns the segments of a {path} value.

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

type Override struct {
	Attribute    string
	Equals       string
	Pattern      string
	SitemapGroup string
}

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 Parse

func Parse(pattern string) (*Pattern, error)

Parse validates and parses a pattern.

func (*Pattern) FirstLiteral

func (p *Pattern) FirstLiteral() string

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) HasDate

func (p *Pattern) HasDate() bool

HasDate reports whether the pattern has a {year}, {month} or {day} token.

func (*Pattern) HasParent

func (p *Pattern) HasParent() bool

HasParent reports whether the pattern has an (optional) {parent} token.

func (*Pattern) HasPath

func (p *Pattern) HasPath() bool

HasPath reports whether the pattern ends in {path}.

func (*Pattern) LiteralCount

func (p *Pattern) LiteralCount() int

LiteralCount is the number of literal segments (higher = more specific).

func (*Pattern) Segments

func (p *Pattern) Segments() []Segment

Segments returns a copy of the parsed segments.

func (*Pattern) String

func (p *Pattern) String() string

String returns the original pattern text.

func (*Pattern) TokenCount

func (p *Pattern) TokenCount() int

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

func (r *Router) CanonicalSchema(schemaSlug string) (string, bool)

CanonicalSchema maps a schema slug or alias to the owning schema's own slug.

func (*Router) Lookup

func (r *Router) Lookup(schemaSlug string, attrs map[string]string) (Target, bool)

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

func (r *Router) Resolve(path string) []Candidate

Resolve returns every candidate whose pattern matches path, most specific first (more literal segments, then fewer tokens, then schema slug order).

func (*Router) SchemaSlugs

func (r *Router) SchemaSlugs(schemaSlug string) []string

SchemaSlugs returns the schema's own slug plus aliases for any known slug.

func (*Router) URLFor

func (r *Router) URLFor(schemaSlug string, attrs map[string]string, v Vars) (string, bool, error)

URLFor renders the canonical path for an entity. It returns false when the schema is unknown to the router; the error reports missing variables.

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 Segment

type Segment struct {
	Literal string
	Token   Token
}

Segment is one path segment: a literal, or a token when Token != TokenNone.

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 Token

type Token int

Token identifies a variable segment.

const (
	// TokenNone marks a literal segment.
	TokenNone Token = iota
	TokenParent
	TokenSlug
	TokenPath
	TokenYear
	TokenMonth
	TokenDay
)

func (Token) String

func (t Token) String() string

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.

func Match

func Match(p *Pattern, path string) (Vars, bool)

Match extracts variables from path. The path must be absolute; a single trailing slash is ignored. A pattern with {parent} also matches the path without that segment (Parent left empty).

Jump to

Keyboard shortcuts

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