I have 10+ pages in blog.
How can I get pagination like that:
I mean, that I want to have the points in pagination when I have many pages.
I have 10+ pages in blog.
How can I get pagination like that:
I mean, that I want to have the points in pagination when I have many pages.
See https://github.com/spf13/hugo/pull/3472
Note that this is the internal Hugo pagination template – and in an unreleased version, it’s not even merged into master. It looks like you are using a custom template (or a theme’s template), but I guess you could find some inspiration in my template.
Here’s an alternate take on the idea. I left out the first/prev/next/last buttons, since they’re redundant, and made the number of buttons constant. The $window
variable controls how much context you see on each side of the active page, so that the total number of buttons is $window * 2 + 5
; setting it to 1 gives 7 buttons, 2 gives 9, etc. If there are less pages than that, it will just show them all.
With Bootstrap for styling, it looks like this:
{{ $pag := $.Paginator }}
{{ $window := 1 }}
{{ if gt $pag.TotalPages 1 }}
{{ $total := $pag.TotalPages }}
{{ $size := add 5 (add $window $window) }}
{{ $cur := $pag.PageNumber }}
{{ if gt $total $size }}
{{ if lt $cur (sub $size 2) }}
{{ $.Scratch.Set "show" (seq 1 (sub $size 2)) }}
{{ else if lt (sub $total $cur) (sub $size 3) }}
{{ $.Scratch.Set "show" (seq (add (sub $total $size) 3) $total) }}
{{ else }}
{{ $.Scratch.Set "show" (seq (sub $cur $window) (add $cur $window)) }}
{{ end }}
{{ $.Scratch.Add "show" 1 }}
{{ $.Scratch.Add "show" $total }}
{{ else }}
{{ $.Scratch.Set "show" (seq 1 $total) }}
{{ end }}
<ul class="pagination">
{{ range $pag.Pagers }}
{{ $cur := .PageNumber }}
{{ if in ($.Scratch.Get "show") $cur }}
<li
{{ if eq . $pag }}class="active"{{ end }}><a href="{{ .URL }}">{{ .PageNumber }}</a></li>
{{ else if in (slice 2 (sub $total 1)) $cur }}
<li class="disabled"><a name="">…</a></li>
{{ end }}
{{ end }}
</ul>
{{ end }}
Ugly, I know, but I prototyped it in a language with better arithmetic and array handling.
-j
Perfect!
Add next and prev button
{{ $pag := $.Paginator }}
{{ $window := 1 }}
{{ if gt $pag.TotalPages 1 }}
{{ $total := $pag.TotalPages }}
{{ $size := add 5 (add $window $window) }}
{{ $cur := $pag.PageNumber }}
{{ if gt $total $size }}
{{ if lt $cur (sub $size 2) }}
{{ $.Scratch.Set "show" (seq 1 (sub $size 2)) }}
{{ else if lt (sub $total $cur) (sub $size 3) }}
{{ $.Scratch.Set "show" (seq (add (sub $total $size) 3) $total) }}
{{ else }}
{{ $.Scratch.Set "show" (seq (sub $cur $window) (add $cur $window)) }}
{{ end }}
{{ $.Scratch.Add "show" 1 }}
{{ $.Scratch.Add "show" $total }}
{{ else }}
{{ $.Scratch.Set "show" (seq 1 $total) }}
{{ end }}
<div class="listing">
{{ if $pag.HasPrev }}
<a class="listing_page" href="{{ $pag.Prev.URL }}">{{ T "Blog_Previous" }}</a>
{{ end }}
{{ range $pag.Pagers }}
{{ $cur := .PageNumber }}
{{ if in ($.Scratch.Get "show") $cur }}
{{ if eq . $pag }}<span>{{ .PageNumber }}</span>
{{ else }}
<a href="{{ .URL | relLangURL }}">{{ .PageNumber }}</a>
{{ end }}
{{ else if in (slice 2 (sub $total 1)) $cur }}
<span class="listing_dot">...</span>
{{ end }}
{{ end }}
{{ if $pag.HasNext }}
<a class="listing_page" href="{{ $pag.Next.URL }}">{{ T "Blog_Next" }}</a>
{{ end }}
</div>
{{ end }}
How are they redundant? We could ask @darbaga, an expert on this: Does having Next, Previous, First and Last buttons add value to visually impaired users? I guess one could add these lables to the respective numbers as well, maybe, but then they would not that easy to find.
Hi,
If I understand correctly, what is being proposed is just numbered pages instead of having prev/nex/first/last buttons right?
If so, that’s perfectly fine. The traditional way i’ve seen it done is to make the current page be not a link, which gives enough context to understand which page i’m on.
I don’t know how well any paginator design works for the visually impaired, or for anyone, actually. I spent an hour searching for best practices, and nothing I found showed any signs of user-interaction testing; a lot about visual design, a (very) little about accessibility, and nothing at all about effective implementation.
So I took @igramnet’s desired example and implemented what I thought its behaviors were. Pages 1 and N are equivalent to First and Last, and are always shown. At least one Previous and one Next page are always shown (more if $window > 1), and CSS makes the active page distinct. If having them labeled first/last/prev/next is important for accessibility, that’s an easy modification, but I don’t see the value in presenting two sets of buttons that do the exact same thing.
After writing it and trying it out on my site, though, I reverted to my previous pager, which always has exactly five buttons: First, Prev, current, Next, Last, with a tooltip for Last that contains TotalPages.
-j
Update: corrected code for all $window sizes (tested from 0-8):
Original code ($window size 2):
1: 1+ 2 3 4 5 6 7 . 12
2: 1 2+ 3 4 5 6 7 . 12
3: 1 2 3+ 4 5 6 7 . 12
4: 1 2 3 4+ 5 6 7 . 12
5: 1 2 3 4 5+ 6 7 . 12
6: 1 2 3 4 5 6+ 7 . 12
7: 1 . 6 7+ 8 9 10 11 12
8: 1 . 6 7 8+ 9 10 11 12
9: 1 . 6 7 8 9+ 10 11 12
10: 1 . 6 7 8 9 10+ 11 12
11: 1 . 6 7 8 9 10 11+ 12
12: 1 . 6 7 8 9 10 11 12+
Revised:
1: 1+ 2 3 4 5 6 7 . 12
2: 1 2+ 3 4 5 6 7 . 12
3: 1 2 3+ 4 5 6 7 . 12
4: 1 2 3 4+ 5 6 7 . 12
5: 1 2 3 4 5+ 6 7 . 12
6: 1 . 4 5 6+ 7 8 . 12
7: 1 . 5 6 7+ 8 9 . 12
8: 1 . 6 7 8+ 9 10 11 12
9: 1 . 6 7 8 9+ 10 11 12
10: 1 . 6 7 8 9 10+ 11 12
11: 1 . 6 7 8 9 10 11+ 12
12: 1 . 6 7 8 9 10 11 12+
{{ $pag := $.Paginator }}
{{ $window := $.Site.Params.paginateWindow | default 1 }}
{{ if gt $pag.TotalPages 1 }}
{{ $total := $pag.TotalPages }}
{{ $size := add 5 (add $window $window) }}
{{ $cur := $pag.PageNumber }}
{{ if gt $total $size }}
{{ if lt $cur (sub $size (add $window 1)) }}
{{ $.Scratch.Set "show" (seq 1 (sub $size 2)) }}
{{ else if lt (sub $total $cur) (sub $size (add $window 2)) }}
{{ $.Scratch.Set "show" (seq (add (sub $total $size) 3) $total) }}
{{ else }}
{{ $.Scratch.Set "show" (seq (sub $cur $window) (add $cur $window)) }}
{{ end }}
{{ $.Scratch.Add "show" 1 }}
{{ $.Scratch.Add "show" $total }}
{{ else }}
{{ $.Scratch.Set "show" (seq 1 $total) }}
{{ end }}
<ul class="pagination">
{{ range $pag.Pagers }}
{{ $cur := .PageNumber }}
{{ if in ($.Scratch.Get "show") $cur }}
<li
{{ if eq . $pag }}class="active"{{ end }}><a href="{{ .URL }}">{{ .PageNumber }}</a></li>
{{ else if in (slice 2 (sub $total 1)) $cur }}
<li class="disabled"><a name="">…</a></li>
{{ end }}
{{ end }}
</ul>
{{ end }}