Add newer/older navigation to the photo detail page

Replace the standalone Back link with a three-cell nav row so each
photo page links to its neighbours in the timeline. Prefetch the
neighbouring pages and bind the arrow keys for keyboard navigation.
This commit is contained in:
2026-07-03 23:03:54 +02:00
parent 856439f3fd
commit 3639bd5577
3 changed files with 55 additions and 11 deletions
+12 -3
View File
@@ -108,8 +108,15 @@ func (g *Generator) Build() error {
if err := g.renderIndexPages(photos); err != nil { if err := g.renderIndexPages(photos); err != nil {
return err return err
} }
for _, p := range photos { for i := range photos {
if err := g.renderPhotoPage(p); err != nil { var newer, older *Photo
if i > 0 {
newer = &photos[i-1]
}
if i+1 < len(photos) {
older = &photos[i+1]
}
if err := g.renderPhotoPage(photos[i], newer, older); err != nil {
return err return err
} }
} }
@@ -358,13 +365,15 @@ func (g *Generator) renderIndexPages(photos []Photo) error {
} }
// renderPhotoPage writes public/photo/<slug>/index.html. // renderPhotoPage writes public/photo/<slug>/index.html.
func (g *Generator) renderPhotoPage(p Photo) error { func (g *Generator) renderPhotoPage(p Photo, newer, older *Photo) error {
dir := filepath.Join(g.outputDir, "photo", p.Slug) dir := filepath.Join(g.outputDir, "photo", p.Slug)
if err := os.MkdirAll(dir, 0755); err != nil { if err := os.MkdirAll(dir, 0755); err != nil {
return err return err
} }
return g.render("photo.html", filepath.Join(dir, "index.html"), map[string]any{ return g.render("photo.html", filepath.Join(dir, "index.html"), map[string]any{
"Photo": p, "Photo": p,
"Newer": newer,
"Older": older,
"BaseURL": g.baseURL, "BaseURL": g.baseURL,
"Year": time.Now().Year(), "Year": time.Now().Year(),
"Author": g.author, "Author": g.author,
+24 -7
View File
@@ -195,17 +195,34 @@ body {
padding: 16px 20px; padding: 16px 20px;
} }
.back-btn { .photo-nav {
display: inline-block; display: flex;
font-size: 15px; justify-content: space-between;
color: var(--fg3); align-items: center;
text-decoration: none;
padding: 8px 0; padding: 8px 0;
margin-bottom: 16px; margin-bottom: 16px;
font-family: var(--serif); font-family: monospace;
font-size: 13px;
letter-spacing: 0.04em;
} }
.back-btn:hover { .photo-nav a {
color: var(--aqua);
text-decoration: none;
}
.photo-nav a:hover {
color: var(--fg2);
}
.photo-nav .back-btn {
font-family: var(--serif);
font-size: 15px;
color: var(--fg3);
letter-spacing: 0;
}
.photo-nav .back-btn:hover {
color: var(--fg); color: var(--fg);
} }
+19 -1
View File
@@ -8,10 +8,16 @@
<link rel="stylesheet" href="/static/style.css"> <link rel="stylesheet" href="/static/style.css">
<style>:root { --serif: '{{.SerifFamily}}', Georgia, serif; --mj: '{{.MlFamily}}', sans-serif; }</style> <style>:root { --serif: '{{.SerifFamily}}', Georgia, serif; --mj: '{{.MlFamily}}', sans-serif; }</style>
<link rel="alternate" type="application/atom+xml" href="/feed.xml" title="Photo Feed"> <link rel="alternate" type="application/atom+xml" href="/feed.xml" title="Photo Feed">
{{if .Newer}}<link rel="prefetch" href="/photo/{{.Newer.Slug}}/">{{end}}
{{if .Older}}<link rel="prefetch" href="/photo/{{.Older.Slug}}/">{{end}}
</head> </head>
<body> <body>
<div class="photo-page"> <div class="photo-page">
<a href="/" class="back-btn">← Back</a> <nav class="photo-nav">
{{if .Newer}}<a href="/photo/{{.Newer.Slug}}/" data-nav="newer">← Newer</a>{{else}}<span></span>{{end}}
<a href="/" class="back-btn">← Back</a>
{{if .Older}}<a href="/photo/{{.Older.Slug}}/" data-nav="older">Older →</a>{{else}}<span></span>{{end}}
</nav>
<div class="dlayout"> <div class="dlayout">
<div class="dimg-wrap"> <div class="dimg-wrap">
<a href="/{{.Photo.File}}" target="_blank" rel="noopener"> <a href="/{{.Photo.File}}" target="_blank" rel="noopener">
@@ -33,5 +39,17 @@
<footer class="site-footer"> <footer class="site-footer">
© 2000{{.Year}} {{.Author}}. All rights reserved. © 2000{{.Year}} {{.Author}}. All rights reserved.
</footer> </footer>
<script>
(function () {
const newer = document.querySelector('[data-nav="newer"]');
const older = document.querySelector('[data-nav="older"]');
document.addEventListener('keydown', (e) => {
if (e.target.matches('input, textarea')) return;
if (e.key === 'ArrowLeft' && newer) location.href = newer.href;
if (e.key === 'ArrowRight' && older) location.href = older.href;
});
})();
</script>
</body> </body>
</html> </html>