let a site root override the theme, and serve static/

A site's templates/ is parsed after the embedded set, so the last definition of a
name wins and a theme redefines one block while inheriting the document
(ADR-0019). Per kind exactly two files are overlaid — base.html and that kind's
block — because overlaying every site template into every set lets a listing's
"main" leak into bundle pages, which is the collision per-kind sets exist to
prevent. Both directions are tested.

templates/theme.css in the site root replaces the reference stylesheet outright;
there is no merging to reason about. static/ is served verbatim under /static/,
through the same os.Root-backed fs.FS, and directory paths answer 404 so it never
indexes its own contents.

Queue entries 6 and 7 are deferred again with triggers: the cascade's consumers are
stage toggles, view selection and cache flags — none of which exist — and declared
types are read by ordering, feeds and check, none of which have landed. Building
either now is the speculation that justified withdrawing them.

Evidence: a real site override renders <section class="mine"> inside the embedded
document with canonical intact, the listing still uses the embedded block, and
/static/site.css and /static/img/logo.svg are 200 while /static/ and /static/img/
are 404.
This commit is contained in:
2026-07-30 02:12:24 +06:00
parent 85a49068d2
commit 499d107314
7 changed files with 204 additions and 29 deletions
+4 -4
View File
@@ -1,6 +1,6 @@
# State
**Verified against:** `2b6cdc7` on 2026-07-30 — update this line every change.
**Verified against:** `85a4906` on 2026-07-30 — update this line every change.
If this file disagrees with the code, the code is right and this file is a bug.
## Inventory
@@ -9,10 +9,10 @@ If this file disagrees with the code, the code is right and this file is a bug.
|---|---|---|
| `go.mod` | module `khosra`; `x/text`, `yaml.v3` direct | 8 |
| `internal/content/content.go` | site root → bundles: `os.Root` open, walk, frontmatter split, key/lang derivation, NFC, collision drop, key index, language fallback, alias index, URL building | 358 |
| `internal/render/render.go` | goldmark + the embedded reference theme; `Page` is what templates receive | 92 |
| `internal/render/templates/` | reference theme: `base.html`, `theme.css` (ADR-0026) | — |
| `internal/render/render.go` | goldmark, per-kind template sets with site override, `Page`/`List`/`head` | 214 |
| `internal/render/templates/` | reference theme: `base.html`, `page.html`, `list.html`, `theme.css` (ADR-0026) | — |
| `internal/web/resolve.go` | URL → (key, lang) or a canonical redirect: language prefix, `/en/…` fork guard, trailing slash | 56 |
| `internal/web/web.go` | handler: resolve, look up with fallback, render, degrade on failure | 62 |
| `internal/web/web.go` | handler: resolve, look up with fallback, listings, `/static/`, degrade on failure | 62 |
| `cmd/khosra/main.go` | flags, wiring, startup — the only place things are assembled | 50 |
| `*_test.go` | table-driven; symlink escape, permalink, redirect, 404 | 245 |