serve Atom feeds for the site, a section and a tag
Membership is a publication date, not a type declaration (ADR-0043). The parked
feed shape said "every type declared primary", which would have made feeds wait on
declared types a third time — but the thing that distinguishes a feed item is
already on disk. Pages and section landings drop out because they have no date,
which is the right reason. The parked idea stays parked with a sharper trigger:
someone wanting a *dated* bundle kept out.
Built with encoding/xml from typed structs, never a template: XML in html/template
is escaping for the wrong grammar, and that is a correctness trap rather than a
matter of taste.
A bug the evidence found, older than feeds: content.URL("", lang) built "//", so a
whole-site feed's id and alternate link were https://khosra.example// — every
entry identity wrong in every reader. The root is "/" now, with a test, and the
hand-built "/" the resolver carried for the same reason can follow later.
Two counters re-scoped rather than incremented, the same way transforms was:
Views now counts *per-bundle selection* — the thing architecture.md means by the
View layer, still at zero consumers. Output formats are not it: HTML, sitemap XML
and Atom are three functions with nothing to share, so an interface over them
would have one member and no leverage.
Effects stays at 1. A feed is generated per request like the sitemap, so it is not
a second Effect and the runner is not yet due — the next thing that writes files
off the request path is.
This commit is contained in:
@@ -364,11 +364,18 @@ const PerPage = 10
|
||||
|
||||
// URL is the permalink of a variant: /{section}/{slug}/, with a language prefix for anything but the
|
||||
// default locale (ADR-0008, ADR-0009). Templates never build a path by hand.
|
||||
//
|
||||
// An empty key is the site root, which is "/" and not "//" — the case a feed for the whole site asks for.
|
||||
func URL(key, lang string) string {
|
||||
if lang == "" || lang == DefaultLang {
|
||||
return "/" + key + "/"
|
||||
prefix := ""
|
||||
if lang != "" && lang != DefaultLang {
|
||||
prefix = lang
|
||||
}
|
||||
return "/" + lang + "/" + key + "/"
|
||||
segments := path.Join(prefix, key)
|
||||
if segments == "" {
|
||||
return "/"
|
||||
}
|
||||
return "/" + segments + "/"
|
||||
}
|
||||
|
||||
// TagURL is the permalink of a tag listing, optionally narrowed to a section (ADR-0018).
|
||||
|
||||
@@ -65,6 +65,16 @@ func TestURLPrefixesOnlyNonDefaultLanguages(t *testing.T) {
|
||||
t.Errorf("URL(pages/about, %q) = %q, want %q", lang, got, want)
|
||||
}
|
||||
}
|
||||
// The site root is "/", not "//" — what a whole-site feed asks for, and what a doubled slash would put in
|
||||
// front of every reader as a broken identity.
|
||||
for lang, want := range map[string]string{"en": "/", "": "/", "bn": "/bn/"} {
|
||||
if got := URL("", lang); got != want {
|
||||
t.Errorf("URL(\"\", %q) = %q, want %q", lang, got, want)
|
||||
}
|
||||
}
|
||||
if got := PageURL("", "en", 2); got != "/page/2/" {
|
||||
t.Errorf("PageURL at the root = %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAliasesAreParsedAndIndexed(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user