On this page
Building one documentation site out of several constituent projects plus a docs-site's own cross-cutting content, each mounted under its own declared slug.
#internal/blog/unified
#internal/blog/unified
Package unified builds one documentation site out of several constituent projects plus a docs-site's own cross-cutting content.
Each constituent project is built from its own selfdoc.json; the docs-site's config supplies the orchestration through its "unified" block, which names the projects, their slugs and their navigation titles. Every project is mounted under its slug, the docs-site's own pages under "common", and the posts of every project land in the one site-level "blog/" tree they share.
[BuildUnified] is the entry point. It wipes the output directory, injects every project's posts into that project's docs tree, partitions the pages, builds one pass per docs-site version, constituent and locale, and then writes the files that belong to the site rather than to a page: the landing page listing the projects, the shared stylesheet, the auxiliary documents, the root redirect stub, the Cloudflare redirect rule, the search index over the whole tree and the compressed companions.
#The docs-site is the (N+1)th project
Its own pages are a mount like any other, which is what makes the landing page's card links and the shared stylesheet hop correct: both are computed from the landing page's own address rather than from a site-root path that would only resolve when the site is served from an origin root.
#Every write and every subprocess is declared
Nothing here touches the filesystem's mutating calls or os/exec directly: each is routed through the effects handle the caller passes in, so a --dry-run records the whole unified build instead of performing it. Reads are not effects and use the standard library.
#ResolveProjectPath
func ResolveProjectPath(projectEntry map[string]any, docsSiteDir string) (string, error)ResolveProjectPath resolves a constituent project's absolute path from its entry in the unified config.
The entry's "path" is stated relative to the docs-site directory, e.g. "../core". A path that does not name a directory is a ConfigError: the whole unified build is described by these entries, so a typo here would otherwise surface as a missing page somewhere far downstream.
#ProjectSlug
func ProjectSlug(projectEntry map[string]any) stringProjectSlug is the URL segment a constituent project is mounted under: the entry's explicit "slug" when it states one, else the last component of its path.
#ProjectNavTitle
func ProjectNavTitle(projectEntry map[string]any) stringProjectNavTitle is the navigation title a constituent project carries: the entry's explicit "nav_title" when it states one, else its slug with the separators turned into spaces and every word title-cased.
#BuildUnified
func BuildUnified(BuildUnified builds a unified documentation site from several constituent projects and returns the paths it wrote.
dirPath is the docs-site's own project root. cfg is a pre-loaded config; nil loads selfdoc.json from dirPath. theme overrides the theme the config declares, for this build only -- empty means the config decides. includeDrafts includes the draft posts of every project.
The docs-site's "unified" block names the constituents; its "versions" and "locales" arrays drive the passes. Each constituent is built from its own selfdoc.json under its own slug, the docs-site's own pages under "common", and every project's posts once into the shared site-level tree. Posts are injected into each project's docs tree before the build and removed afterwards whether the build succeeded or failed.