Commit f4cdc0af49

f4cdc0af496e3812e103fd86cd4dc22074f8ae10

parent: bbfca815b0

Verified · cmc

cmc <hello@cleberg.net> · 2026-09-17 15:44 UTC

web: content width chosen per page

Ref #218
internal/web/templates/404.html +1
@@ -1,3 +1,4 @@
1{{define "width"}}bounded{{end}}
12{{define "title"}}not found · {{.Site}}{{end}}
23{{define "content"}}
34<div class="notfound">
internal/web/templates/account.html +1
@@ -1,3 +1,4 @@
1{{define "width"}}bounded{{end}}
12{{define "title"}}account settings{{end}}
23{{define "content"}}
34<h1>Account settings</h1>
internal/web/templates/admin.html +1
@@ -1,3 +1,4 @@
1{{define "width"}}bounded{{end}}
12{{define "title"}}admin · {{.Site}}{{end}}
23{{define "content"}}
34<h1>Admin</h1>
internal/web/templates/blame.html +1
@@ -1,3 +1,4 @@
1{{define "width"}}wide{{end}}
12{{define "title"}}blame: {{.Path}} · {{.Repo.OwnerName}}/{{.Repo.Name}}{{end}}
23{{define "content"}}
34<h1 class="vh">Blame: {{.Path}}</h1>
internal/web/templates/blob.html +1
@@ -1,3 +1,4 @@
1{{define "width"}}wide{{end}}
12{{define "title"}}{{.Path}} · {{.Repo.OwnerName}}/{{.Repo.Name}}{{end}}
23{{define "content"}}
34<h1 class="vh">{{.Path}}</h1>
internal/web/templates/build.html +1
@@ -1,3 +1,4 @@
1{{define "width"}}wide{{end}}
12{{define "title"}}build {{.Build.Number}} · {{.Repo.OwnerName}}/{{.Repo.Name}}{{end}}
23{{define "content"}}
34{{if .Notice}}<p class="error" role="alert">{{.Notice}}</p>{{end}}
internal/web/templates/builds.html +1
@@ -1,3 +1,4 @@
1{{define "width"}}wide{{end}}
12{{define "title"}}builds · {{.Repo.OwnerName}}/{{.Repo.Name}}{{end}}
23{{define "content"}}
34<h1>Builds</h1>
internal/web/templates/commit.html +1
@@ -1,3 +1,4 @@
1{{define "width"}}wide{{end}}
12{{define "title"}}{{.ShortSHA}} · {{.Repo.OwnerName}}/{{.Repo.Name}}{{end}}
23{{define "content"}}
34<div class="commithead">
internal/web/templates/compare.html +1
@@ -1,3 +1,4 @@
1{{define "width"}}wide{{end}}
12{{define "title"}}compare {{.Base}}...{{.Head}} · {{.Repo.OwnerName}}/{{.Repo.Name}}{{end}}
23{{define "content"}}
34<h1>Compare <code>{{.Base}}</code><code>{{.Head}}</code></h1>
internal/web/templates/edit.html +1
@@ -1,3 +1,4 @@
1{{define "width"}}bounded{{end}}
12{{define "title"}}edit {{.Path}} · {{.Repo.OwnerName}}/{{.Repo.Name}}{{end}}
23{{define "content"}}
34<h1>edit {{.Repo.OwnerName}}/{{.Repo.Name}} : {{.Path}} @ {{.Ref}}</h1>
internal/web/templates/globalsearch.html +1
@@ -1,3 +1,4 @@
1{{define "width"}}wide{{end}}
12{{define "title"}}search · {{.Site}}{{end}}
23{{define "content"}}
34<div class="listhead">
internal/web/templates/issuenew.html +1
@@ -1,3 +1,4 @@
1{{define "width"}}bounded{{end}}
12{{define "title"}}new issue · {{.Repo.OwnerName}}/{{.Repo.Name}}{{end}}
23{{define "content"}}
34<h1>New issue</h1>
internal/web/templates/landing.html +1
@@ -1,3 +1,4 @@
1{{define "width"}}bounded{{end}}
12{{define "title"}}{{.Site}}{{end}}
23{{define "content"}}
34<div class="landing">
internal/web/templates/layout.html +2 −1
@@ -91,7 +91,7 @@
9191</header>
9292{{end}}
9393
94<main id="content" class="content">
94<main id="content" class="content {{template "width" .}}">
9595{{template "content" .}}
9696</main>
9797
@@ -104,6 +104,7 @@
104104</html>{{end}}
105105
106106{{define "mark"}}<svg class="mark" width="19" height="19" viewBox="0 0 24 24" aria-hidden="true"><path d="M12 2.25 18.75 12H5.25z" fill="#ff6b3d"/><rect x="3" y="13.5" width="18" height="3" fill="currentColor"/><rect x="7.5" y="18" width="9" height="3" fill="currentColor"/></svg>{{end}}
107{{define "width"}}reading{{end}}
107108
108109{{define "reporow"}}<li>
109110 <p class="reponame"><a href="/{{.OwnerName}}/{{.Name}}">{{.OwnerName}}<span class="sep">/</span><strong>{{.Name}}</strong></a>{{if eq .Visibility "private"}} <span class="chip">Private</span>{{end}}{{if .Archived}} <span class="chip">Archived</span>{{end}}</p>
internal/web/templates/log.html +1
@@ -1,3 +1,4 @@
1{{define "width"}}wide{{end}}
12{{define "title"}}log · {{.Repo.OwnerName}}/{{.Repo.Name}}{{end}}
23{{define "content"}}
34<h1 class="vh">Commits</h1>
internal/web/templates/login.html +1
@@ -1,3 +1,4 @@
1{{define "width"}}bounded{{end}}
12{{define "title"}}login · {{.Site}}{{end}}
23{{define "content"}}
34<h1>Sign in</h1>
internal/web/templates/mrnew.html +1
@@ -1,3 +1,4 @@
1{{define "width"}}bounded{{end}}
12{{define "title"}}new merge request · {{.Repo.OwnerName}}/{{.Repo.Name}}{{end}}
23{{define "content"}}
34<h1>New merge request</h1>
internal/web/templates/new.html +1
@@ -1,3 +1,4 @@
1{{define "width"}}bounded{{end}}
12{{define "title"}}new repository · {{.Site}}{{end}}
23{{define "content"}}
34<h1>New repository</h1>
internal/web/templates/privacy.html +1
@@ -1,3 +1,4 @@
1{{define "width"}}bounded{{end}}
12{{define "title"}}privacy · {{.Site}}{{end}}
23{{define "content"}}
34<div class="landing">
internal/web/templates/register.html +1
@@ -1,3 +1,4 @@
1{{define "width"}}bounded{{end}}
12{{define "title"}}register · {{.Site}}{{end}}
23{{define "content"}}
34<div class="landing">
internal/web/templates/registered.html +1
@@ -1,3 +1,4 @@
1{{define "width"}}bounded{{end}}
12{{define "title"}}welcome · {{.Site}}{{end}}
23{{define "content"}}
34<div class="landing">
internal/web/templates/search.html +1
@@ -1,3 +1,4 @@
1{{define "width"}}wide{{end}}
12{{define "title"}}search · {{.Repo.OwnerName}}/{{.Repo.Name}}{{end}}
23{{define "content"}}
34<h1>Search</h1>
internal/web/templates/settings.html +1
@@ -1,3 +1,4 @@
1{{define "width"}}bounded{{end}}
12{{define "title"}}settings · {{.Repo.OwnerName}}/{{.Repo.Name}}{{end}}
23{{define "content"}}
34{{$base := printf "/%s/%s/settings" .Repo.OwnerName .Repo.Name}}
internal/web/templates/snippetnew.html +1
@@ -1,3 +1,4 @@
1{{define "width"}}bounded{{end}}
12{{define "title"}}new snippet · {{.Owner}}{{end}}
23{{define "content"}}
34<h1>New snippet</h1>
internal/web/templates/tree.html +1
@@ -1,3 +1,4 @@
1{{define "width"}}wide{{end}}
12{{define "title"}}{{.Repo.OwnerName}}/{{.Repo.Name}}{{end}}
23{{define "content"}}
34{{if .Notice}}<p class="error" role="alert">{{.Notice}}</p>{{end}}
internal/web/web_test.go +33
@@ -83,3 +83,36 @@ func TestWhenNamesTheZone(t *testing.T) {
8383 t.Fatalf("passthrough: %q", got)
8484 }
8585}
86
87// TestMainWidthClass renders every page against an empty struct and
88// checks main carries exactly one width class, and that the pages the
89// spec calls wide or bounded say so.
90func TestMainWidthClass(t *testing.T) {
91 wide := map[string]bool{"tree.html": true, "blob.html": true, "blame.html": true, "log.html": true, "commit.html": true, "compare.html": true, "builds.html": true, "build.html": true, "search.html": true, "globalsearch.html": true}
92 bounded := map[string]bool{"landing.html": true, "login.html": true, "register.html": true, "registered.html": true, "new.html": true, "issuenew.html": true, "mrnew.html": true, "settings.html": true, "account.html": true, "admin.html": true, "edit.html": true, "snippetnew.html": true, "privacy.html": true, "404.html": true}
93 for _, name := range Pages() {
94 src, err := TemplateSource(name)
95 if err != nil {
96 t.Fatal(err)
97 }
98 has := strings.Contains(src, `{{define "width"}}`)
99 switch {
100 case wide[name] && !strings.Contains(src, `{{define "width"}}wide{{end}}`):
101 t.Errorf("%s: want width wide", name)
102 case bounded[name] && !strings.Contains(src, `{{define "width"}}bounded{{end}}`):
103 t.Errorf("%s: want width bounded", name)
104 case !wide[name] && !bounded[name] && has:
105 t.Errorf("%s: defines a width but the spec calls it reading", name)
106 }
107 }
108 layout, err := TemplateSource("layout.html")
109 if err != nil {
110 t.Fatal(err)
111 }
112 if !strings.Contains(layout, `<main id="content" class="content {{template "width" .}}">`) {
113 t.Error("layout.html: main does not carry the width block")
114 }
115 if !strings.Contains(layout, `{{define "width"}}reading{{end}}`) {
116 t.Error("layout.html: no default width")
117 }
118}