Determine if current page is result of pagination

Is there a way of determining from within a template/partial whether the current page is the result of pagination? I’ve tried looking for the present of .Paginator.URL, but that’s caused errors.

1 Like

I haven’t needed to figure this out, but I did recall a similar idea being shared here before:

Relevant snippet:

{{- $siteTitle := .Site.Title -}}
{{ if ne .Kind "page" }}
{{ $pag := .Paginate (where .Data.Pages "Section" "blog") }}
    <title>{{ .Site.Title }} {{ if $pag.HasPrev }}• Page {{ .Paginator.PageNumber }} of {{ .Paginator.TotalPages }}{{ end }}</title>
{{- else if .IsPage -}}
    <title>{{ $title }} • {{ $siteTitle }}</title>
{{- end -}}

Which takes advantage of (Pagination | Hugo):

HasPrev
Whether there are page(s) before the current

HasNext
Whether there are page(s) after the current

Thanks, @maiki! This is semi similar to how I most recently tried which is using .Paginator.PageNumber to determine if it’s greater than 1, however doing so seems to be creating pagination pages for those that shouldn’t. For instance, my home page now has localhost:1313/page/2/.

1 Like

Setup

layouts/_default/
├── baseof.html  <-- in here, before the main block, you want to know if the current page is a pager, and if so, which pager?
├── home.html
├── list.html    <-- in here you do {{ range (.Paginate .Pages 5).Pages }}
└── single.html

Logical but flawed approach

A logical but flawed approach is to place something like this in baseof.html

{{ with .Paginator }}
  Current pager number: {{ .PageNumber }}
{{ end }}

And there are many posts in this forum where site authors have tried this, only to later discover the unpleasant side effects.

Unpleasant side effects in this example

1) We inadvertently paginated the home page.
2) Our list page won’t show 5 pages per pager, but will instead use the paginate site configuration value (default is 10).

Why does this happen?

Because both the .Paginate and .Paginator methods cause pagination to occur, and the first one to be invoked wins.
https://gohugo.io/templates/pagination/#list-paginator-pages

If you call .Paginator or .Paginate multiple times on the same page, you should ensure all the calls are identical. Once either .Paginator or .Paginate is called while generating a page, its result is cached, and any subsequent similar call will reuse the cached result. This means that any such calls which do not match the first one will not behave as written.

What should we do?

It would be great if the .Paginator method did not cause pagination to occur, but instead simply gave you access to the properties once pagination has occurred (e.g., .PageNumber, .HasPrev, .HasNext, etc.). This may not be possible due to concurrency or the rendering sequence.

That’s probably worthy of a GitHub issue, and definitely a breaking change, but in my view worth the trouble given how often this problem arises.

What can we do right now?

In our example, let’s place this in list.html

{{ range (.Paginate .Pages 5).Pages }}
  <h2><a href="{{ .RelPermalink }}">{{ .Title }}</a></h2>
{{ end }}
{{ template "_internal/pagination.html" . }}
{{ .Store.Set "paginator_number_of_pagers" .Paginator.TotalPages }}

Now, in baseof.html we can reliably retrieve the number of pagers (which might be just 1) with:

{{ with .Store.Get "paginator_number_of_pagers" }}
  Number of pagers: {{ . }}
{{ end }}

I emphasize reliably because, due to concurrency, other useful paginator properties such as .PageNumber cannot be passed reliably using a .Store or .Scratch.

OK, great, so we know how many pagers, but what we really want to know is, which pager?

We cannot parse the .RelPermalink due to this issue, so we need to take a different approach:

3 Likes

this was also a fight for me in the last 2 weeks…

Every page in paging should have different titles and descriptions, got this from an verifier back.

@bep
Can we have a .GetPager as page function? Give back null/nil if no pager is there.

here my changed list.html with page numbers, if anyone need it - must change the classes

{{ define "main" }}
<header>
	{{ $pages := site.GetPage .Section }}	{{ $paginator := .Paginate $pages.Pages 20}}
	<h1><span>{{ site.Title | markdownify }}</span><i class="ph3 fas fa-dragon fa-fw"></i>{{ .Page.Title }} {{ $paginator.PageNumber }}</h1>
	{{if isset .Params "description" }}<div class="f5 b w-90-ns pb1">{{ .Description }} {{ $paginator.PageNumber }}</div>{{end}}
</header>	
	<h2 class=dn>{{ .Page.Title }}</h2>
	<article>
		<div class=liste>
			{{ range $paginator.Pages -}}
			{{ .Render "summary" }}
			{{- end }}
		</div>
		{{ partial "pagination" . }}
	</article>
{{ end }}
2 Likes