Hugo 自带的分页导航功能其实也不错,但是它有一个很让人不舒服的地方,就是它生成了太多的空行(blank lines),这个问题已经很多年了,貌似官方也不关注这块儿,到目前为止最新版的 Hugo(v0.62.0)依然如此。
按理说,在大括号内侧加上 -
,像这样:{{- -}}
,可以自动清理掉代码块前后多余的空行,但是不知为什么,自带的 pagination 模板貌似没这么做。从源代码来看,这个 pager 有多少省略掉的页面,就会产生多少空行,这样在看源代码时太丑了,如果只有几页,那感觉不出来,但是如果是几十上百页的话,就会有大片的空白,让人很不舒服,问题的关键是你还不能消除,因为 pager 是被调用的,你在外面包裹再多的 -
也白搭,影响不到它内部。
那能不能自己写一个 pager 呢?当然可以,稍微熟悉 Hugo 模板应该就能照着文档自己写一个分页导航条(pager)。但是转念一想,其他 CMS 有没有现成的比较好的呢?看了看 WordPress 的,也不太喜欢,无意中发现了 Discuz 论坛的分页导航条,感觉正合适,Discuz 的分页导航条功能可以说是非常完备了,而且能看出它的作者肯定考虑的非常周全,对于导航条的各种需求,作者非常清楚,这个真的是大赞。
于是我就照着 Discuz 的分页 Function(DiscuzX 3.4,位于 /uc_server/model/base.php
)自己用 Hugo 模板语言来实现了一下,因为自己对于 Go template 也不是很熟悉,过程中遇到很多问题,花了很长时间,不过最终还是翻版过来了😄,实际测试好像也没什么问题。
需要注意的几点:
- variable 需要在用之前先声明好,也就是代码前面那几行。
- Go template 没有 for loop,需要用
range
。 - Hugo 本身与 Discuz 的区别,导致某些页面,比如 taxonomy 的首页,url 规则(
$contextURL
)是不一样的,所以额外多出了一些替换。 - 另外,Discuz 的代码是直接 concatenate 的,而因为上面的原因以及两者语法的不同,我直接把每条(代码中的
chain
部分)依次罗列下来了。
好了,下面是 Hugo 版的自定义分页导航条(custom pager)代码,水平有限,博主不保证 100% 正确和可移植 🙃,(pager 的具体样子可见本站分页部分):
{{- $num := len (where .Site.RegularPages "Type" "post") -}}
{{- $perpage := 7 -}}
{{- $curpage := .Paginator.PageNumber -}}
{{- $contextURL := "" -}}
{{- $to := 1 -}}
{{- $from := 1 -}}
{{- if eq .Kind "taxonomy" -}}
{{- if eq .Data.Singular "category" -}}
{{- $contextURL = printf "%s%s%s" "/categories/" (.Title | urlize | lower ) "/page/" -}}
{{- else -}}
{{- $contextURL = printf "%s%s%s" "/tags/" (.Title | urlize | lower ) "/page/" -}}
{{- end -}}
{{- else -}}
{{- $contextURL = "/page/" -}}
{{- end -}}
{{- if ge .Paginator.TotalPages 2 -}}
{{- if gt $num $perpage -}}
{{- $span := 5 -}}
{{- $offset := 2 -}}
{{- $pages := .Paginator.TotalPages -}}
{{- if gt $span $pages -}}
{{- $from = 1 -}}
{{- $to = $pages -}}
{{- else -}}
{{- $from = sub $curpage $offset -}}
{{- $to = sub (add $from $span) 1 -}}
{{- if lt $from 1}}
{{- $to = sub (add $curpage 1) $from -}}
{{- $from = 1 -}}
{{- if lt (sub $to $from) $span -}}
{{- $to = $span -}}
{{- end -}}
{{- else if gt $to $pages -}}
{{- $from = add (sub $pages $span) 1 -}}
{{- $to = $pages -}}
{{- end -}}
{{- end -}}
{{- $chain1 := cond (and (gt (sub $curpage $offset) 1) (gt $pages $span )) (printf "%s%s%d%s" "<li class=\"page-item\"><a class=\"page-link\" href=" $contextURL 1 ".html>❰❰ 1 ...</a></li>" | safeHTML) "" -}}
{{- if eq $contextURL "/page/" -}}
{{- $chain1Replaced := replace $chain1 "/page/1.html" "/" | safeHTML -}}
{{- $chain1Replaced -}}
{{- else -}}
{{- $chain1Replaced := replace $chain1 "/page/1.html" ".html" | safeHTML -}}
{{- $chain1Replaced -}}
{{- end -}}
{{- if .Paginator.HasPrev -}}
<li class="page-item"><a class="page-link" href="{{- .Paginator.Prev.URL -}}">❮ 上一页</a></li>
{{- end -}}
{{- if le $from $to}}
{{- range $i, $sequence := last (add (sub $to $from) 1 ) (seq $to) -}}
<li class="page-item">
{{- $chain3 := cond (eq $sequence $curpage) (printf "%s%s%d%s%d%s" "<a class=\"page-link\" id=\"active\" href=" $contextURL $sequence ".html>" $sequence "</a>" | safeHTML) (printf "%s%s%d%s%d%s" "<a class=\"page-link\" href=" $contextURL $sequence ".html>" $sequence "</a>" | safeHTML) -}}
{{- if eq $contextURL "/page/" -}}
{{- $chain3Replaced := replace $chain3 "/page/1.html" "/" | safeHTML -}}
{{- $chain3Replaced -}}
{{- else -}}
{{- $chain3Replaced := replace $chain3 "/page/1.html" ".html" | safeHTML -}}
{{- $chain3Replaced -}}
{{- end -}}
</li>
{{- end -}}
{{- end -}}
{{- if .Paginator.HasNext -}}
<li class="page-item"><a class="page-link" href="{{- .Paginator.Next.URL -}}">下一页 ❯</a></li>
{{- end -}}
{{- $chain5 := cond (lt $to $pages) (printf "%s%s%d%s%d%s" "<li class=\"page-item\"><a class=\"page-link\" href=" $contextURL $pages ".html>... " $pages " ❱❱</a></li>" | safeHTML) "" -}}
{{- $chain5 -}}
{{- end -}}
{{- end -}}