消解炼金术

04_hugo内置语法上下篇功能实现

小岛建设

这也算是一个从notion跳出来选择自搭博客的关键原因了,点开阅读后要手动返回之前页面,然后又要重新定位位置跳转新文章,也许notion有插件或功能可以实现这个功能,但hugo自带还是太方便了,如果是所有文章上下翻页:

{{ with .Prev}}   //{{ with .Next}}
<a href=".RelPermalink">
{{end}}

hugo的.Prev和.Next并不对应字面意义,.Next指向排序列表中索引更小的,.Prev指向索引更大的。特定Section内实现排序也可以用.PrevInSectioin和.NextInSection实现。

但如果目录是多层文件夹嵌套结构:

->content/A/a-a.md
->content/A/a-b.md
->content/A/a-c.md

并希望实现专题下所有文章的前后篇翻阅,到尽头指向另一专题,就无法通过已有模块实现了。起初用了一套非常冗杂的代码实现,用到了hugo的稳定排序(stable sort)和索引赋值:

{{ $allPages := where .Site.RegularPages "Section" .Section }}
{{ $allPages = sort $allPages "File.Path" }}
{{ $allPages := sort $allPages "File.BaseFileName" }}

{{ $currentIndex := -1 }}
{{ range $index, $page := $allPages }}
{{ if eq $page $ }}
{{ $currentIndex = $index }}
{{ end }}
{{ end }}
{{ $parentSection := .CurrentSection.Parent }}  //获取父栏目
{{ $grandParentSections := sort $parentSection.Parent.Sections "File.Path" }} //获取所有同级父栏目
{{ $parentIndex := -1 }} //当前父栏目的索引
{{ range $index, $section := $grandParentSections }}
{{ if eq $section.File.Path $parentSection.File.Path }}
{{ $parentIndex = $index }}
{{ end }}

{{ if lt $currentIndex (sub (len $allPages) 1) }}
{{ with index $allPages (add $currentIndex 1) }}
<a href="{{ .RelPermalink }}">
    上一篇</a>
{{ end }}
{{ if gt $currentIndex 0 }}
{{ with index $allPages (sub $currentIndex 1) }}
<a href="{{ .RelPermalink }}">
    下一篇</a>
{{ end }}

但一旦设计到一些特殊页面,比如:

->content/introduce.md

生成就会报错,于是就要添加更多判断,既不美观,又不直观。针对这种情况hugo其实也已经给出了其他自订制方案,比如使用.FirstSection -> content下所有的一级文件夹。

方案一-ByWeight:

{{ $pages:=.FirstSection.RegularPagesRecursive.ByWeight }}
{{with $pages.Next}}
<a href=".RelPermalink">上一篇</a>
{{end}}
{{with $pages.Prev}}
<a href=".RelPermalink">下一篇</a>
{{end}}

方案二-sort:

{{$pages:=sort .Site.Section "File.BaseFilename"}}
{{with $pages.Prev}} //上一篇
{{with $pages.Next}} //下一篇

第一篇和最后一篇的专题间切换,用if判断添加到方案一/二的下面:

{{ $sections := .Site.Sections }}
{{ $sections = sort $sections "File.Path" }}
{{ $prevSection := $sections.Next .FirstSection }}
//下一专题 {{ $nextSection := $sections.Prev .FirstSection }}
{{ with $PrevSection }}
<a href="{{ .RelPermalink }}">上一专题</a>
{{ end }}

因为是静态页面,所以选择了便于专题内阅读的翻页处理,如果希望直观地按总览排序:

{{ $pages := sort .Site.RegularPages "Date" "asc"}}

其实.Prev/.Next就可以直接实现这个方案了,但sort可以配合front matter定义更多排序字段,比如:

{{ $pages := sort .Site.RegularPages "Params.order" "desc" }}

再结合稳定排序的特性,也可以自定义多样性排序。

© 2026 消解炼金术 | 
Powered by Hugo and Cloudflare