add paginated section index pages

The first collection page earns the Query primitive: content.Query{Section, Lang}
with Site.Run, newest first, undated after dated, ties broken by key so the same
query always answers in the same order. No cache signature — nothing caches, and a
signature with no consumer is speculation.

Pagination lives in the path (ADR-0028): page one is the bare listing URL,
/page/1/ redirects to it, and a page past the end is 404 rather than an empty page,
because an empty page is a URL that means nothing. `page` is therefore a reserved
segment inside a section, now recorded in content-model.md.

Two kinds of page means two parsed template sets already — base plus the block that
kind defines — which is ADR-0019's per-type shape arriving by need rather than by
anticipation. A head struct is embedded in both Page and List so base.html has one
contract, and theme-contract.md gains the listing fields.

Bundle gains Date, accepting an unquoted YAML date or an RFC 3339 string, since
yaml.v3 hands back time.Time for one and a string for the other.

Evidence: 12 posts → /posts/ shows 10 with rel=next to /posts/page/2/,
/posts/page/2/ shows 3 with rel=prev to /posts/, ordering is post-12 11 10,
/posts/page/1/ 301s to /posts/, /posts/page/9/ is 404, /bn/posts/ is 200.
This commit is contained in:
Claude Opus 5
2026-07-30 02:08:12 +06:00
committed by bdeshi
parent 01ac1bf431
commit c8006e7358
12 changed files with 394 additions and 46 deletions
+2 -7
View File
@@ -4,7 +4,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{if .Title}}{{.Title}}{{else}}{{.Key}}{{end}}</title>
<title>{{.Title}}</title>
<link rel="canonical" href="{{.Canonical}}">
{{- range .Alternates}}
<link rel="alternate" hreflang="{{.Lang}}" href="{{.URL}}">
@@ -13,12 +13,7 @@
</head>
<body>
<main>
{{block "main" . -}}
<article>
{{if .Title}}<h1>{{.Title}}</h1>{{end}}
{{.HTML}}
</article>
{{- end}}
{{- template "main" .}}
</main>
</body>
</html>
+20
View File
@@ -0,0 +1,20 @@
{{define "main" -}}
<h1>{{.Title}}</h1>
{{if .Items -}}
<ul class="listing">
{{- range .Items}}
<li><a href="{{.URL}}">{{if .Title}}{{.Title}}{{else}}{{.Key}}{{end}}</a>
{{- if not .Date.IsZero}} <time datetime="{{.Date.Format "2006-01-02"}}">{{.Date.Format "2 January 2006"}}</time>{{end}}</li>
{{- end}}
</ul>
{{- else}}
<p>Nothing here yet.</p>
{{- end}}
{{- if or .PrevURL .NextURL}}
<nav class="pagination">
{{- if .PrevURL}}<a rel="prev" href="{{.PrevURL}}">Newer</a>{{end}}
<span>Page {{.Page}} of {{.Pages}}</span>
{{- if .NextURL}}<a rel="next" href="{{.NextURL}}">Older</a>{{end}}
</nav>
{{- end}}
{{- end}}
+6
View File
@@ -0,0 +1,6 @@
{{define "main" -}}
<article>
{{if .Title}}<h1>{{.Title}}</h1>{{end}}
{{.HTML}}
</article>
{{- end}}