Skip to content

Commit a217639

Browse files
committed
Put headers and redirects logic in data partials
Add a page documenting the Hugo theme
1 parent c777664 commit a217639

9 files changed

Lines changed: 226 additions & 63 deletions

File tree

hugo-theme-hedgerules/layouts/index.hedgeheaders.json

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -2,47 +2,8 @@
22
33
Outputs a JSON file mapping paths to objects of HTTP headers.
44
Format: {"/path/": {"Header-Name": "value"}, "/": {"Default-Header": "value"}}
5-
6-
Header sources (merged in this order, later wins):
7-
1. params.HedgerulesPathHeaders from hugo.toml (root "/" for global defaults)
8-
2. HedgerulesHeaders from page frontmatter (exact page paths)
9-
10-
The viewer-response function does two KVS lookups: exact path, then root "/".
11-
Exact-path headers take priority over root defaults.
12-
135
*/ -}}
14-
15-
{{- /* Start with an empty dict of headers */ -}}
16-
{{- $headers := dict -}}
17-
18-
{{- /* Merge all non-page-path headers from site config */ -}}
19-
{{- range $path, $headerDict := .Site.Params.HedgerulesPathHeaders -}}
20-
{{- $existingHeaders := dict -}}
21-
{{- if isset $headers $path -}}
22-
{{- $existingHeaders = index $headers $path -}}
23-
{{- end -}}
24-
{{- $pathHeaders := merge $existingHeaders $headerDict -}}
25-
{{- $headers = merge $headers (dict $path $pathHeaders) -}}
26-
{{- end -}}
27-
28-
{{- /* Merge all page headers from frontmatter */ -}}
29-
{{- range .Site.Pages -}}
30-
{{- $path := .RelPermalink -}}
31-
{{- $headerDict := dict -}}
32-
{{- if .Params.HedgerulesHeaders -}}
33-
{{- $headerDict = merge $headerDict .Params.HedgerulesHeaders -}}
34-
{{- end -}}
35-
{{- if gt (len $headerDict) 0 -}}
36-
{{- $existingHeaders := dict -}}
37-
{{- if isset $headers $path -}}
38-
{{- $existingHeaders = index $headers $path -}}
39-
{{- end -}}
40-
{{- $pathHeaders := merge $existingHeaders $headerDict -}}
41-
{{- $headers = merge $headers (dict $path $pathHeaders) -}}
42-
{{- end -}}
43-
{{- end -}}
44-
45-
{{- /* Output all the headers as JSON */ -}}
6+
{{- $headers := partial "hedgerules/headers.html" . -}}
467
{{ $headers | jsonify (dict "indent" " ") -}}
478

489
{{- /* -*- mode: go-template; -*- */ -}}

hugo-theme-hedgerules/layouts/index.hedgeredirects.txt

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,12 @@
33
Outputs a redirects file that Hedgerules reads.
44
Each line: /source /destination
55

6-
Sources:
7-
1. Site-wide custom redirects from params.HedgerulesRedirects
8-
2. Hugo aliases from page frontmatter
9-
3. Per-page path redirects from HedgerulesPathRedirects frontmatter
10-
116
Directory index redirects (/path -> /path/) are NOT included here;
127
Hedgerules generates those by scanning the build output.
13-
148
*/ -}}
159
# Redirects generated by Hugo
1610
# Format: /source /destination
17-
# Site-wide custom redirects
18-
{{ range $source, $dest := .Site.Params.HedgerulesRedirects -}}
11+
{{- $redirects := partial "hedgerules/redirects.html" . -}}
12+
{{- range $source, $dest := $redirects }}
1913
{{ $source }} {{ $dest }}
20-
{{ end -}}
21-
# Hugo aliases and per-page path redirects
22-
{{- range .Site.AllPages -}}
23-
{{- $dest := .RelPermalink -}}
24-
{{- range .Aliases }}
25-
{{ . }} {{ $dest }}
26-
{{- end -}}
27-
{{- range .Params.HedgerulesPathRedirects }}
28-
{{- $to := .to -}}
29-
{{- if hasPrefix $to "/" -}}
30-
{{ .from }} {{ $to }}
31-
{{- else -}}
32-
{{ .from }} {{ printf "%s%s" $dest $to }}
33-
{{- end -}}
34-
{{- end -}}
3514
{{- end }}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{{- /* Return a map of all headers (path -> {header: value, ...}).
2+
*
3+
* Sources (merged in this order, later wins):
4+
* 1. params.HedgerulesPathHeaders from hugo.toml
5+
* 2. HedgerulesHeaders from page frontmatter
6+
*
7+
* We use scratch instead of dict+merge because scratch mutates in place,
8+
* avoiding the repeated allocations that merge requires (it returns a new
9+
* dict every time).
10+
*
11+
* The result is cached on hugo.Store so it is only computed once per build.
12+
*/ -}}
13+
14+
{{- $s := hugo.Store -}}
15+
{{- if not ($s.Get "hedgerules_headers") -}}
16+
{{- $m := newScratch -}}
17+
18+
{{- range $path, $headerDict := site.Params.HedgerulesPathHeaders -}}
19+
{{- $existing := $m.Get $path -}}
20+
{{- if $existing -}}
21+
{{- $m.Set $path (merge $existing $headerDict) -}}
22+
{{- else -}}
23+
{{- $m.Set $path $headerDict -}}
24+
{{- end -}}
25+
{{- end -}}
26+
27+
{{- range $p := site.Pages -}}
28+
{{- if $p.Params.HedgerulesHeaders -}}
29+
{{- $path := $p.RelPermalink -}}
30+
{{- $existing := $m.Get $path -}}
31+
{{- if $existing -}}
32+
{{- $m.Set $path (merge $existing $p.Params.HedgerulesHeaders) -}}
33+
{{- else -}}
34+
{{- $m.Set $path $p.Params.HedgerulesHeaders -}}
35+
{{- end -}}
36+
{{- end -}}
37+
{{- end -}}
38+
39+
{{- $s.Set "hedgerules_headers" ($m.Values) -}}
40+
{{- end -}}
41+
42+
{{- return ($s.Get "hedgerules_headers") -}}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{{- /* Render an HTML table of all headers. */ -}}
2+
{{- $headers := partial "hedgerules/headers.html" . -}}
3+
<table>
4+
<thead>
5+
<tr><th>Path</th><th>Header</th><th>Value</th></tr>
6+
</thead>
7+
<tbody>
8+
{{- range $path, $headerDict := $headers -}}
9+
{{- range $name, $value := $headerDict }}
10+
<tr><td>{{ $path }}</td><td>{{ $name }}</td><td>{{ $value }}</td></tr>
11+
{{- end -}}
12+
{{- end }}
13+
</tbody>
14+
</table>
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{{- /* Return a map of all redirects (source -> destination).
2+
*
3+
* Sources (in this order):
4+
* 1. Site-wide custom redirects from params.HedgerulesRedirects
5+
* 2. Hugo aliases from page frontmatter
6+
* 3. Per-page path redirects from HedgerulesPathRedirects frontmatter
7+
*
8+
* We use scratch instead of dict+merge because scratch mutates in place,
9+
* avoiding the repeated allocations that merge requires (it returns a new
10+
* dict every time).
11+
*
12+
* The result is cached on hugo.Store so it is only computed once per build.
13+
*/ -}}
14+
15+
{{- $s := hugo.Store -}}
16+
{{- if not ($s.Get "hedgerules_redirects") -}}
17+
{{- $m := newScratch -}}
18+
19+
{{- range $source, $dest := site.Params.HedgerulesRedirects -}}
20+
{{- $m.Set $source $dest -}}
21+
{{- end -}}
22+
23+
{{- range $p := site.AllPages -}}
24+
{{- range $a := $p.Aliases -}}
25+
{{- $m.Set $a $p.RelPermalink -}}
26+
{{- end -}}
27+
{{- range $r := $p.Params.HedgerulesPathRedirects -}}
28+
{{- $to := $r.to -}}
29+
{{- if hasPrefix $to "/" -}}
30+
{{- $m.Set $r.from $to -}}
31+
{{- else -}}
32+
{{- $m.Set $r.from (printf "%s%s" $p.RelPermalink $to) -}}
33+
{{- end -}}
34+
{{- end -}}
35+
{{- end -}}
36+
37+
{{- $s.Set "hedgerules_redirects" ($m.Values) -}}
38+
{{- end -}}
39+
40+
{{- return ($s.Get "hedgerules_redirects") -}}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{{- /* Render an HTML table of all redirects. */ -}}
2+
{{- $redirects := partial "hedgerules/redirects.html" . -}}
3+
<table>
4+
<thead>
5+
<tr><th>Source</th><th>Destination</th></tr>
6+
</thead>
7+
<tbody>
8+
{{- range $source, $dest := $redirects }}
9+
<tr><td>{{ $source }}</td><td>{{ $dest }}</td></tr>
10+
{{- end }}
11+
</tbody>
12+
</table>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{{- /* Shortcode to render an HTML table of all Hedgerules headers.
2+
*
3+
* Usage in markdown:
4+
* {{< hedgerulesHeadersTable >}}
5+
*/ -}}
6+
{{ partial "hedgerules/headersTable.html" . }}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{{- /* Shortcode to render an HTML table of all Hedgerules redirects.
2+
*
3+
* Usage in markdown:
4+
* {{< hedgerulesRedirectsTable >}}
5+
*/ -}}
6+
{{ partial "hedgerules/redirectsTable.html" . }}

www/content/docs/theme/_index.md

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
---
2+
title: "Hugo Theme"
3+
weight: 55
4+
---
5+
6+
The `hugo-theme-hedgerules` Hugo theme provides output format layouts, data partials, and table partials for working with Hedgerules headers and redirects.
7+
8+
## Output format layouts
9+
10+
These templates generate the files that `hedgerules deploy` reads.
11+
12+
### `index.hedgeheaders.json`
13+
14+
Generates `_hedge_headers.json`, a JSON file mapping paths to HTTP header objects. Enable it via `[outputs]` in `hugo.toml`:
15+
16+
```toml
17+
[outputs]
18+
home = ["HTML", "hedgeheaders", "hedgeredirects"]
19+
```
20+
21+
### `index.hedgeredirects.txt`
22+
23+
Generates `_hedge_redirects.txt`, a text file with one `source destination` pair per line. Enable it alongside `hedgeheaders` as shown above.
24+
25+
## Data partials
26+
27+
These partials return data and can be called from your own templates or shortcodes.
28+
29+
### `hedgerules/redirects.html`
30+
31+
Returns a map of all redirects (source path to destination path). Sources are collected in this order:
32+
33+
1. Site-wide `HedgerulesRedirects` from `hugo.toml`
34+
2. Hugo `aliases` from page frontmatter
35+
3. `HedgerulesPathRedirects` from page frontmatter
36+
37+
The result is cached on `hugo.Store` so it is only computed once per build.
38+
39+
```go-html-template
40+
{{ $redirects := partial "hedgerules/redirects.html" . }}
41+
{{ range $source, $dest := $redirects }}
42+
{{ $source }} -> {{ $dest }}
43+
{{ end }}
44+
```
45+
46+
### `hedgerules/headers.html`
47+
48+
Returns a map of all headers (path to header dict). Sources are merged in this order (later wins):
49+
50+
1. `HedgerulesPathHeaders` from `hugo.toml`
51+
2. `HedgerulesHeaders` from page frontmatter
52+
53+
The result is cached on `hugo.Store` so it is only computed once per build.
54+
55+
```go-html-template
56+
{{ $headers := partial "hedgerules/headers.html" . }}
57+
{{ range $path, $headerDict := $headers }}
58+
{{ $path }}:
59+
{{ range $name, $value := $headerDict }}
60+
{{ $name }}: {{ $value }}
61+
{{ end }}
62+
{{ end }}
63+
```
64+
65+
## Table partials and shortcodes
66+
67+
These partials render HTML tables and are useful for documentation or debugging pages.
68+
69+
### `hedgerules/redirectsTable.html`
70+
71+
Renders an HTML table with Source and Destination columns for all redirects.
72+
73+
```go-html-template
74+
{{ partial "hedgerules/redirectsTable.html" . }}
75+
```
76+
77+
This is also available as a shortcode.
78+
79+
```markdown
80+
{{</* hedgerules/redirectsTable */>}}
81+
```
82+
83+
On this site, it renders like this:
84+
85+
{{< hedgerules/redirectsTable >}}
86+
87+
### `hedgerules/headersTable.html`
88+
89+
Renders an HTML table with Path, Header, and Value columns for all headers.
90+
91+
```go-html-template
92+
{{ partial "hedgerules/headersTable.html" . }}
93+
```
94+
95+
This is also available as a shortcode.
96+
97+
```markdown
98+
{{</* hedgerules/headersTable */>}}
99+
```
100+
101+
On this site, it renders like this:
102+
103+
{{< hedgerules/headersTable >}}

0 commit comments

Comments
 (0)