Range with pagination is not working

<div class="post-entries">
    {{ $posts := where .Site.RegularPages "Type" "posts" }}
    {{ $paginate := .Paginate $posts }}
    {{ range $paginate.Pages }}
        <article class="post-card">
            <a href="{{ .RelPermalink }}">
                {{ with .Params.featured_image }}
                    {{ $featured_image := resources.Get . }}
                    {{ if $featured_image }}
                        <img loading="lazy" width="{{ $featured_image.Width }}" height="{{ $featured_image.Height }}" src="{{ $featured_image.Permalink }}" alt="{{ $.Title }}">
                    {{ end }}
                {{ end }}

                <h3>{{ .Title | safeHTML }}</h3>
                <p>{{.Type}}</p>

            </a>
        </article>
    {{ end }}
</div>

I am doing this to get posts form specific section, but from other types are also showing. I have also tried {{ $posts := where .Site.RegularPages "Section" "posts" }}, but it’s not working. please help and tell me where I’m mistaken!

try this: {{ $posts := where (where .Site.Pages "Type" "page") "Section" "posts" }}

mmh, looks like we mix up Type and Kind here.

  • Page Type:
    The content type is defined by the type field in front matter, or inferred from the top-level directory name if the type field in front matter is not defined.

  • Page Kind
    A page kind is a classification of pages, one of home , page , section , taxonomy , or term

So it depends of how YOU specify the type ‘posts’ of pages.

  • by front matter on every page or cascade it down
  • toplevel directory
  • a mixture of both

.Site.RegularPages returns only pages of Kind ‘page’,

so: Where .Site.RegularPages "Section" "posts" will return all normal pages below the toplevel folder content/pages. Should be the same as Where .Site.RegularPages "Type" posts" unless you have different type of pages using front matter values below /content/posts

Keep in mind, that with front matter type = "post" is different from type = "posts"

I could think of a double paginate call on your list page.

Please note that the results of pagination are cached. Once you have invoked either the Paginator or Paginate method, the paginated collection is immutable. Additional invocations of these methods will have no effect.

My content folder structure look like this!

content/categories (term)
content/post (type will be post - not defined in frontmatter)
content/page (type will be page)
content/_index.md (home)
content/normal-page.md (a page)
content/search.md (layout: search)

I want to use the top-level folder name for that. because I don’t want to add type: post or type: posts, I want to use the folder name as type.

In this case the {{ $posts := where .Site.RegularPages "Type" "post" }} should work. but it’s giving me all of those inside content. like normal-page, search and each post in post content folder

If I don’t paginate then it returns all content files from post folder

means without pagination it works as expected?

yes. It works.


This is with pagination.


This is without pagination

so it’s in you layout files. as i said i suppose you paginate twice, maybe a context issue

easiest would be to share your repo

all the files are currently hosted locally. which is why I couldn’t share right now.

I think yes there was double pagination. as _default/list.html also has pagination, and index.html uses a different partial with pagination in it too.

If there’s double pagination, how can I fix this?

honestly, I have no clue…didn’t play with paginators yet

1 Like

I debuged the issue. So now. Please tell me a better way to do this.

head.html

<!-- Robots -->
{{- if or (.Params.noindex) (and .IsNode .Paginator.HasPrev) -}}
<meta name="robots" content="noindex, follow">
{{- else -}}
<meta name="robots" content="index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1">
{{- end -}}

{{ with (and .IsNode .Paginator) }}
<link rel="canonical" href="{{ .URL | absURL }}">
<meta property="og:url" content="{{ .URL | absURL }}">
<meta property="twitter:url" content="{{ .URL | absURL }}">
{{ else }}
<link rel="canonical" href="{{ .Permalink }}">
<meta property="og:url" content="{{ .Permalink }}">
<meta property="twitter:url" content="{{ .Permalink }}">
{{ end }}

index.html

{{ if not .Paginator.HasPrev }}
<section id="top_trending">
    <h2 style="text-align: center;">Trending Posts</h2>
    {{ partial "home/trending.html" . }}
</section>
{{ end }}

<section id="latest_post">
    <h2 style="text-align: center;">Latest Post</h2>
    {{ partial "home/list.html" . }}
</section>

{{ if not .Paginator.HasPrev }}
<article>{{ .Content }}</article>
{{ end }}

the list.html contains the main pagination.

The Paginator is invoking multiple times, which is the better way to do so?

can you help now!

as I said I’m not in Paginators, but this one seems weird: {{ if not .Paginator.HasPrev }}

I would have expected there’s one call to .Paginate the collection returning a Pager

{{ $pager := .Paginate page collection }}

and then use methods of that one.

{{ if $pager.HasPrev }}

i’m out here… hope you have time to jump in @jmooring

1 Like

I am really confused right now, but this is important. Let’s wait for @jmooring reply! If he can help!

Calling either .Paginate or .Paginator paginates a page collection, the result of which is cached. This is covered in the documentation.

If you need access to the .Paginator early in the template (e.g., within the head element), read this:
https://discourse.gohugo.io/t/pagination-using-pager-values-within-the-head-element/50340

1 Like

First load you paginator collection with the content you need to paginate on :
{{ $paginator := .Paginate (where .Data.Pages "Section" "posts" ) 21 }}

or in your case
{{ $paginator := .Paginate (where .Site.RegularPages "Type" "posts") 21 }}
( 21 is the number of elements on each paginated page, it can be any int value. )

Then you can iterate over the $paginator object as you would with anything else.
For instance :
{{ range $paginator.Pages }}

Finally you can call the pagination itself, it will take advantage of the $paginator collection

       <div class="col-lg-12">
         <div class="pagination pagi1">
           {{ template "_internal/pagination.html" . }}
         </div>
       </div>

That’s all there is to it.
(One of many ways to do it)

Not if you need to access the Paginator early in the template, before you’ve defined the page collection to be paginated, which is what this topic is about.

Thank You for the solution!
This is what I did!

robots

{{ $robotsnoindex := `<meta name="robots" content="noindex, follow">` }}
{{ $robotsindex := `<meta name="robots" content="index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1">` }}

<!-- Robots Meta Tag -->
{{ if .IsNode }}
  {{ block "pagination" . }}{{ end }}
  {{ $paginator := .Store.Get "paginator" }}
  {{ with $paginator.HasPrev }}
    {{ $robotsnoindex | safeHTML }}
  {{ else }}
    {{ $robotsindex | safeHTML }}
  {{ end }}
{{ else if not .IsNode }}
  {{- if .Params.noindex -}}
    {{ $robotsnoindex | safeHTML }}
  {{- else -}}
    {{ $robotsindex | safeHTML }}
  {{- end -}}
{{ end }}

canonical

{{ if .IsNode }}
  {{ block "pagination" . }}{{ end }}
  {{ $paginator := .Store.Get "paginator" }}
  {{ with $paginator }}
    <link rel="canonical" href="{{ .URL | absURL }}">
    <meta property="og:url" content="{{ .URL | absURL }}">
    <meta property="twitter:url" content="{{ .URL | absURL }}">
  {{ end }}
{{ else }}
<link rel="canonical" href="{{ .Permalink | absURL }}">
<meta property="og:url" content="{{ .Permalink | absURL }}">
<meta property="twitter:url" content="{{ .Permalink | absURL }}">
{{ end }}
1 Like

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.