mykiwi/mykiwi.blogpublic Fork
⑂ a823897
Commits
⬇ Clone ▾
git clone https://git.rickub.com/mykiwi/mykiwi.blog.git
git clone ssh://git@rickub.com/mykiwi/mykiwi.blog.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Download ZIP

Link every page to its own source at the revision it was built fromUnverified

Borrowed from fzakaria.com's site-foot: an "Improve this page" link
in the footer, pointing at the page's own content file on the forge.
It goes to /blob/<rev>/<path> at the exact revision the site was
built from, not to main, so a reader who follows it from a deployed
page reads the source that produced what they were just looking at
rather than whatever main has moved on to since.

The revision comes from the flake: self.rev exists only for a clean
tree, so `hugo server` and a `nix build` over uncommitted changes
both fall back to the branch, which is also the default sitting in
hugo.toml.

Two small things the template has to be careful about. Hugo's
path.Join cleans its result, which would turn https:// into https:/,
so only the in-repo path is joined with it and the URL is printf'd.
And pages Hugo generates without a content file - the home page, the
post list - have no .File at all, so the link is wrapped in a `with`
and those pages simply do not get one.

No hx-boost="false" needed, unlike the RSS and language links next
to it: htmx only boosts same-origin anchors and the forge is another
host.
Romain Gautier committed 2026-09-20T14:42:34+02:00 Browse files
a823897 parent: f158010
modified blog/hugo.toml +12 -0
@@ -84,6 +84,18 @@ weight = 5
8484 # flip to false (or delete the line) once the site is ready to be found.
8585 noindex = true
8686
87+# Footer "Improve this page" link: <repoURL>/blob/<repoCommit>/<repoContentPath>/<the
88+# page's own source file>. The forge serves a file at a given revision under
89+# /blob/<ref>/<path>, and .File.Path is relative to blog/content/, which is what
90+# repoContentPath prepends.
91+repoURL = "https://rickub.com/mykiwi/mykiwi.blog"
92+repoContentPath = "blog/content"
93+# Overridden by the Nix build (HUGO_PARAMS_REPOCOMMIT, see flake.nix) with the
94+# revision the site was built from, so a deployed page links to the source it was
95+# actually rendered from rather than to wherever main has moved since. `hugo
96+# server` and builds from a dirty tree have no revision and keep the branch below.
97+repoCommit = "main"
98+
8799 [params.profile]
88100 # Drop a square photo at blog/assets/images/avatar.jpg (or change this path)
89101 # to have it show up; the colophon quietly skips itself if the file is missing.
@@ -84,6 +84,18 @@ weight = 5
84 # flip to false (or delete the line) once the site is ready to be found.84 # flip to false (or delete the line) once the site is ready to be found.
85 noindex = true85 noindex = true
86 86
87+# Footer "Improve this page" link: <repoURL>/blob/<repoCommit>/<repoContentPath>/<the
88+# page's own source file>. The forge serves a file at a given revision under
89+# /blob/<ref>/<path>, and .File.Path is relative to blog/content/, which is what
90+# repoContentPath prepends.
91+repoURL = "https://rickub.com/mykiwi/mykiwi.blog"
92+repoContentPath = "blog/content"
93+# Overridden by the Nix build (HUGO_PARAMS_REPOCOMMIT, see flake.nix) with the
94+# revision the site was built from, so a deployed page links to the source it was
95+# actually rendered from rather than to wherever main has moved since. `hugo
96+# server` and builds from a dirty tree have no revision and keep the branch below.
97+repoCommit = "main"
98+
87 [params.profile]99 [params.profile]
88 # Drop a square photo at blog/assets/images/avatar.jpg (or change this path)100 # Drop a square photo at blog/assets/images/avatar.jpg (or change this path)
89 # to have it show up; the colophon quietly skips itself if the file is missing.101 # to have it show up; the colophon quietly skips itself if the file is missing.
modified blog/i18n/en.toml +3 -0
@@ -11,6 +11,9 @@ other = "{{ .Count }} min read"
1111 one = "{{ .Count }} post"
1212 other = "{{ .Count }} posts"
1313
14+[improvePage]
15+other = "Improve this page"
16+
1417 [licenseText]
1518 other = "Content is"
1619
@@ -11,6 +11,9 @@ other = "{{ .Count }} min read"
11 one = "{{ .Count }} post"11 one = "{{ .Count }} post"
12 other = "{{ .Count }} posts"12 other = "{{ .Count }} posts"
13 13
14+[improvePage]
15+other = "Improve this page"
16+
14 [licenseText]17 [licenseText]
15 other = "Content is"18 other = "Content is"
16 19
modified blog/i18n/es.toml +3 -0
@@ -11,6 +11,9 @@ other = "{{ .Count }} min de lectura"
1111 one = "{{ .Count }} artículo"
1212 other = "{{ .Count }} artículos"
1313
14+[improvePage]
15+other = "Mejorar esta página"
16+
1417 [licenseText]
1518 other = "Contenido bajo licencia"
1619
@@ -11,6 +11,9 @@ other = "{{ .Count }} min de lectura"
11 one = "{{ .Count }} artículo"11 one = "{{ .Count }} artículo"
12 other = "{{ .Count }} artículos"12 other = "{{ .Count }} artículos"
13 13
14+[improvePage]
15+other = "Mejorar esta página"
16+
14 [licenseText]17 [licenseText]
15 other = "Contenido bajo licencia"18 other = "Contenido bajo licencia"
16 19
modified blog/i18n/fr.toml +3 -0
@@ -11,6 +11,9 @@ other = "{{ .Count }} min de lecture"
1111 one = "{{ .Count }} article"
1212 other = "{{ .Count }} articles"
1313
14+[improvePage]
15+other = "Améliorer cette page"
16+
1417 [licenseText]
1518 other = "Contenu sous licence"
1619
@@ -11,6 +11,9 @@ other = "{{ .Count }} min de lecture"
11 one = "{{ .Count }} article"11 one = "{{ .Count }} article"
12 other = "{{ .Count }} articles"12 other = "{{ .Count }} articles"
13 13
14+[improvePage]
15+other = "Améliorer cette page"
16+
14 [licenseText]17 [licenseText]
15 other = "Contenu sous licence"18 other = "Contenu sous licence"
16 19
modified blog/i18n/ja.toml +3 -0
@@ -10,6 +10,9 @@ other = "{{ .Count }}分で読了"
1010 [postsCount]
1111 other = "{{ .Count }}件の投稿"
1212
13+[improvePage]
14+other = "このページを改善する"
15+
1316 [licenseText]
1417 other = "コンテンツは"
1518
@@ -10,6 +10,9 @@ other = "{{ .Count }}分で読了"
10 [postsCount]10 [postsCount]
11 other = "{{ .Count }}件の投稿"11 other = "{{ .Count }}件の投稿"
12 12
13+[improvePage]
14+other = "このページを改善する"
15+
13 [licenseText]16 [licenseText]
14 other = "コンテンツは"17 other = "コンテンツは"
15 18
modified blog/i18n/pt.toml +3 -0
@@ -11,6 +11,9 @@ other = "{{ .Count }} min de leitura"
1111 one = "{{ .Count }} post"
1212 other = "{{ .Count }} posts"
1313
14+[improvePage]
15+other = "Melhorar esta página"
16+
1417 [licenseText]
1518 other = "Conteúdo sob licença"
1619
@@ -11,6 +11,9 @@ other = "{{ .Count }} min de leitura"
11 one = "{{ .Count }} post"11 one = "{{ .Count }} post"
12 other = "{{ .Count }} posts"12 other = "{{ .Count }} posts"
13 13
14+[improvePage]
15+other = "Melhorar esta página"
16+
14 [licenseText]17 [licenseText]
15 other = "Conteúdo sob licença"18 other = "Conteúdo sob licença"
16 19
modified blog/layouts/partials/site-foot.html +13 -0
@@ -1,4 +1,17 @@
11 <footer class="site-foot column">
2+ {{- /*
3+ Source link for the page you are reading, pointing at the very revision the
4+ site was built from (site.Params.repoCommit, see hugo.toml). Pages Hugo
5+ generates without a content file - the home page, the post list - have no
6+ .File, and get no link.
7+ */}}
8+ {{- with .File }}
9+ {{- $source := path.Join site.Params.repoContentPath .Path }}
10+ <span>
11+ <a href="{{ printf "%s/blob/%s/%s" site.Params.repoURL site.Params.repoCommit $source }}">{{ i18n "improvePage" }}</a>
12+ </span>
13+ <span class="sep" aria-hidden="true">&middot;</span>
14+ {{- end }}
215 <span>{{ i18n "licenseText" }} <a href="{{ i18n "licenseURL" }}">CC BY-SA</a></span>
316 <span class="sep" aria-hidden="true">&middot;</span>
417 <span>
@@ -1,4 +1,17 @@
1 <footer class="site-foot column">1 <footer class="site-foot column">
2+ {{- /*
3+ Source link for the page you are reading, pointing at the very revision the
4+ site was built from (site.Params.repoCommit, see hugo.toml). Pages Hugo
5+ generates without a content file - the home page, the post list - have no
6+ .File, and get no link.
7+ */}}
8+ {{- with .File }}
9+ {{- $source := path.Join site.Params.repoContentPath .Path }}
10+ <span>
11+ <a href="{{ printf "%s/blob/%s/%s" site.Params.repoURL site.Params.repoCommit $source }}">{{ i18n "improvePage" }}</a>
12+ </span>
13+ <span class="sep" aria-hidden="true">&middot;</span>
14+ {{- end }}
2 <span>{{ i18n "licenseText" }} <a href="{{ i18n "licenseURL" }}">CC BY-SA</a></span>15 <span>{{ i18n "licenseText" }} <a href="{{ i18n "licenseURL" }}">CC BY-SA</a></span>
3 <span class="sep" aria-hidden="true">&middot;</span>16 <span class="sep" aria-hidden="true">&middot;</span>
4 <span>17 <span>
modified flake.nix +6 -1
@@ -19,7 +19,12 @@
1919 src = ./blog;
2020 nativeBuildInputs = [ hugo dart-sass ];
2121 buildPhase = ''
22- HUGO_PARAMS_NIXSTOREPATH="$out" hugo --minify --destination "$out"
22+ # self.rev is the revision this flake was built from - it only exists
23+ # when the tree is clean, so a local `nix build` with uncommitted
24+ # changes falls back to the branch, same as `hugo server` does.
25+ HUGO_PARAMS_NIXSTOREPATH="$out" \
26+ HUGO_PARAMS_REPOCOMMIT="${self.rev or "main"}" \
27+ hugo --minify --destination "$out"
2328 '';
2429 dontInstall = true;
2530 };
@@ -19,7 +19,12 @@
19 src = ./blog;19 src = ./blog;
20 nativeBuildInputs = [ hugo dart-sass ];20 nativeBuildInputs = [ hugo dart-sass ];
21 buildPhase = ''21 buildPhase = ''
22- HUGO_PARAMS_NIXSTOREPATH="$out" hugo --minify --destination "$out"22+ # self.rev is the revision this flake was built from - it only exists
23+ # when the tree is clean, so a local `nix build` with uncommitted
24+ # changes falls back to the branch, same as `hugo server` does.
25+ HUGO_PARAMS_NIXSTOREPATH="$out" \
26+ HUGO_PARAMS_REPOCOMMIT="${self.rev or "main"}" \
27+ hugo --minify --destination "$out"
23 '';28 '';
24 dontInstall = true;29 dontInstall = true;
25 };30 };