[SOLVED] Big pagination (need add ... )

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="">&hellip;</a></li>
      {{ end }}
    {{ end }}
  </ul>
{{ end }}

Ugly, I know, but I prototyped it in a language with better arithmetic and array handling. :slightly_smiling:

-j

1 Like

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.

1 Like

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="">&hellip;</a></li>
      {{ end }}
    {{ end }}
  </ul>
{{ end }}
2 Likes