serve a bundle at its permalink

-site (or KHOSRA_SITE) opens the site root through content.OpenSite, so every
read keeps the os.Root guarantee. A path is a bundle key: /{section}/{slug}/
serves, the slashless form redirects permanently to it (ADR-0008), anything
unknown is 404. Render failure logs and returns a bare 500 rather than leaking a
template or filesystem detail.

internal/render holds goldmark plus the embedded reference theme (ADR-0026):
base.html with a redefinable "main" block, and one stylesheet inlined through
.Style. Serving it at an asset route would have been a second routing case for no
gain, and static serving belongs to a later entry.

Evidence beyond the tests: the binary against a real site root returns 200 with
<h1>About</h1> and the rendered body, 301 from /pages/about to /pages/about/, and
404 for /nope/. A Bengali variant is scanned but not yet reachable — that is the
next entry.

theme-contract.md gains a "Live today" section listing the six fields and two
named templates a theme may now rely on; the rest stays marked as shape.
This commit is contained in:
2026-07-30 01:35:50 +06:00
parent db58d382c5
commit 48c1fc9669
13 changed files with 436 additions and 10 deletions
+27
View File
@@ -215,3 +215,30 @@ func dropCollisions(all []Bundle) []Bundle {
}
return kept
}
// Site is a set of bundles indexed for lookup by permalink key.
type Site struct {
byKeyLang map[string]Bundle
}
// NewSite indexes bundles for lookup. Later variants of a key and language cannot occur, because Scan
// drops ambiguity before this sees it.
func NewSite(bundles []Bundle) *Site {
s := &Site{byKeyLang: make(map[string]Bundle, len(bundles))}
for _, b := range bundles {
s.byKeyLang[b.Key+"\x00"+b.Lang] = b
}
return s
}
// Lookup returns the default-locale variant of a key.
//
// Other languages are reachable only once language routing exists; until then a key means its default
// variant (ADR-0021).
func (s *Site) Lookup(key string) (Bundle, bool) {
b, ok := s.byKeyLang[key+"\x00"+DefaultLang]
return b, ok
}
// Len reports how many bundles the site holds.
func (s *Site) Len() int { return len(s.byKeyLang) }