How can I determine the first page of paginated posts?

How can I determine the first page of posts?

What I want to do is find any page of posts that is not the first page so I can add a robots.txt tag to noindex. I don’t want search engines to index any other paginated pages than the first page of posts.

I’m using this is head.html:

{{ $homepage := .Paginate ( where .Site.RegularPages “Type” “posts” ) 5 }}
{{ if $homepage.HasPrev }}

{{ else }}

{{ end }}

but it throws the error <$homepage.HasPrev>: error calling HasPrev: runtime error: invalid memory address or nil pointer dereference.

That error might be from two instances of the paginator, which I call as a partial paginator.html later on in list.html.

Or, is there a better way to determine the first page of posts with a function other than Paginate?

I would use robots.txt.

User-agent: *
Disallow: /*page/*

If you have configured a different pagination path (paginatePath) in config.toml, replace ‘page’ with the value of paginatePath.

But wait, won’t this stop the first page in a paginated list from being indexed? No, because requests for /foo/page/1 are always redirected to /foo/ via a meta-refresh, and /foo/ is allowed in this example of a robots.txt file.

There are several “robots.txt” testing tools to help with the syntax.

Thanks, I’m aware of robots.txt files and noindex directives; but I want to determine the first page of paginated posts in Hugo, both to not have users need to edit or be aware of robots.txt, and for other code reasons.

{{- with .Paginator -}}
  {{- if and .HasNext (not .HasPrev) -}}
    I am the first page.
  {{- end -}}
  {{- if and .HasPrev (not .HasNext) -}}
    I am the last page.
  {{- end -}}
  {{- if and .HasNext .HasPrev -}}
    I am neither the first nor the last page.
  {{- end -}}
{{- end -}}

Thanks, that’s interesting and it works, but it breaks the Paginator, which I call as a partial paginator.html later on in list.html for pagination in the post footer. The breakage results in listing all pages and posts, rather than simply posts. So I need to find some way to determine the first page and other paginated pages without using Paginator.

I hope you’ve made some progress, because I have not.

I’ve got a test site with this layout structure:

baseof
  partial head
  partial header
  block main
    (includes single or list)
  partial footer

I tried setting a Scratch variable within list:

{{- with .Paginator -}}
  {{- if and .HasNext (not .HasPrev) -}}
    {{- $.Scratch.Set "foo" "I am the first page." -}}
  {{- end -}}
  {{- if and .HasPrev (not .HasNext) -}}
    {{- $.Scratch.Set "foo" "I am the last page." -}}
  {{- end -}}
  {{- if and .HasNext .HasPrev -}}
    {{- $.Scratch.Set "foo" "I am neither the first nor the last page." -}}
  {{- end -}}
{{- end -}}

Then I added this to head:

{{- .Scratch.Get "foo" -}}

But, predictably, when accessed from head, the value is null or incorrect, presumably due to rendering sequence or lack thereof (parallelism).

So, then I thought, “Oh well, let’s just parse .RelPermalink to see if it ends with page/n.” But the value of .RelPermalink is the same for all pagers. For example:

URL Shown in Browser .RelPermalink
/post/page/2/ /post/
/post/page/3/ /post/
/post/page/4/ /post/

And of course, /post/page/1 simply redirects to /post/, where the .RelPermalink is /post/ as expected. So, from inside head I have no idea where I am. That’s quotable.

The only solution I’ve come up with is to change the layout structure. If list were the top level (meaning no baseof) we could instantiate the paginator at the top of the template, then set values in head.