Skip to content
internal/address
On this page

The single addressing authority for built pages: the output key, the stable version-free URL, the pinned archive path and the hops back to each root.

#internal/address

#internal/address

Package address is the single addressing authority for built pages.

One function -- [NewPageAddress] -- decides, for a page and the locale, project and version it belongs to, all four things the rest of the build needs:

- OutputKey: where the page file lands under the output root ("guide/index.html" for the current version, "v/1.0.0/guide/index.html" for a superseded one). - Stable: the version-free URL path for the page ("guide/"). This is where the CURRENT version of every page lives, and it is what every version of the page declares canonical. - Pinned: the version-pinned URL path ("v/1.0.0/guide/"). A superseded version is emitted there; the current version's pinned address is the address it will occupy once a newer version supersedes it. - Depth: how many directory levels the output key sits below the output root, and from it the two relative hops every page needs -- [PageAddress.ToSiteRoot] back to the output root, where the shared assets live, and [PageAddress.ToMountRoot] back to this page's own mount, where its sibling pages live.

#The scheme

The current version of every page lives at a stable, unversioned address:

///

Superseded versions live beside it under the archive prefix "v":

//v///

The locale segment is dropped entirely while a site has one locale -- [LocaleSegment] is the one place that decides it -- and the project segment exists only on a unified site. A single-locale standalone site therefore mounts its current version at the output root: "guide/".

"v" is reserved. A top-level page named "v" would collide with the archive tree, so [NewPageAddress] refuses it.

#Why its own package rather than urls

The urls package turns a path into an absolute URL against a configured base (base_url, or a docs base plus a slug). That is a deployment concern -- it answers "what does the world call this page". Addressing answers "where does this page sit in the output tree, and how does it reach its neighbours", which has to be correct with no base URL at all and identical under every mount point. Mixing the two is what produced the depth defect this package replaces: a site's own asset links must never depend on where the site is served from, so they are always document-relative and always derived here.

#ArchivePrefix

Go go
const ArchivePrefix = "v"

ArchivePrefix is the URL segment every archived (superseded) version is emitted under.

#PostsPrefix

Go go
const PostsPrefix = "blog"

PostsPrefix is the site-level URL segment every post is emitted under: "blog//". Fixed, and the same in a standalone build and on the unified site.

#PageAddress

Go go
type PageAddress struct

PageAddress is every address a single built page has.

It is a value type with no pointer fields, so a copy is independent of its original: that is what stands in for the frozen dataclass this replaces. Nothing in the package mutates one after [NewPageAddress] returns it, and a caller should not either -- the addresses are consistent with each other only as constructed.

#Coordinates

Go go
type Coordinates struct

Coordinates are the mount coordinates a page is built under. The zero value is a single-locale standalone site's unversioned page, which is what the Python's keyword defaults expressed.

#IsSiteLevel

Go go
func IsSiteLevel(path string) bool

IsSiteLevel reports whether path addresses the site level rather than a project mount.

Posts are site citizens: they carry no locale, project or version segment, and on an assembled site they are served from the site root at "blog//" while the project that wrote them is served under its own slug. Every surface that has to tell the two apart -- the URL builder deciding whether to write the slug, the sidebar deciding which hop reaches an item -- asks here.

It accepts either form the build speaks: an output path ("blog/hello/index.html") or a URL path ("blog/hello/", "blog/").

Go go
func RootPageLink(mdFilename string) string

RootPageLink is the link written on one root-level docs page to another root-level page.

Every root-level page except index.md is emitted at "/index.html", so a page writing a link is itself inside a directory and a sibling is one level up: "..//". Writing the bare "/" -- correct back when pages were flat ".html" files -- now resolves inside the writing page's own directory and names nothing.

The generated index pages (the API reference and the CLI reference) are the callers: both are always at the docs root, which is what makes the single hop the right one.

#NewPageAddress

Go go
func NewPageAddress(pagePath string, coords Coordinates) (PageAddress, error)

NewPageAddress maps a page and its mount coordinates to every address it has.

pagePath is the mount-relative HTML path, e.g. "guide/index.html". It must be relative, non-empty, and must not start with the reserved archive segment "v/".

#PageAddress.URL

Go go
func (a PageAddress) URL() string

URL is the URL path this page is actually emitted at.

#PageAddress.StableMount

Go go
func (a PageAddress) StableMount() string

StableMount is the version-free mount: where the current version's pages sit.

#PageAddress.ArchiveMount

Go go
func (a PageAddress) ArchiveMount() string

ArchiveMount is the mount superseded copies of this page's version sit under.

#PageAddress.ToSiteRoot

Go go
func (a PageAddress) ToSiteRoot() string

ToSiteRoot is the relative hop from this page's directory to the output root.

#PageAddress.ToMountRoot

Go go
func (a PageAddress) ToMountRoot() string

ToMountRoot is the relative hop from this page's directory to its own mount root.

#PageAddress.ToStableMountRoot

Go go
func (a PageAddress) ToStableMountRoot() string

ToStableMountRoot is the relative hop from this page's directory to the version-free mount.

On a page emitted at the stable address this is the same hop as [PageAddress.ToMountRoot]. On an archive page it climbs two levels further, over "v//".

Search