Frustrated - Trying to set up pagination with nested sections


#1

I’m feeling very frustrated lately with Hugo. Rather than empowering me and making my life easier, I feel like it’s a chain around my neck restricting me and that I’m having to fight it constantly, having to find hacky workarounds for issues that then break other things. I don’t want it to be like this.

What I have:

Nested sections with pages inside them, for example:
/cats/breeds/persian.md
/cats/breeds/siamese.md
/cats/breeds/ragdoll.md
/cats/caring/feeding.md
/cats/caring/grooming.md
/cats/adoption/how-to.md
/dogs/about.md

What I want:

Pagination at the bottom of each page, pointing to the next and previous page. However, I want the links to point to the next or previous page in the current top-level section. For example, if you look at the list of pages above, I want the “Ragdoll” page to link to “Breeds/Siamese” and “Caring/Feeding” (going by alphabetical order for a simpler explanation, but in reality I’d be using weights).

.PrevInSection and .NextInSection only give me links within the nested section (breeds, or caring, or adoption).

.Prev and .Next give me links across the entire site, even in totally unrelated sections (e.g. /dogs/).

I want something in-between. Essentially, I want a .PrevInTopSection and .NextInTopSection, but these don’t seem to exist.

What I’ve tried:

I searched around for this issue and came across a post suggesting to use Hugo’s pagination system for this, with a page size of 1. I read the documentation page and it sounded great:

{{ $paginator := .Paginate (where .Data.Pages "Section" .Section) 1 }}

But no. Hugo fails to build the site with this, giving an error message saying:

<.Paginate>: error calling Paginate: Paginators not supported for pages of type "page"

For some reason, pagination only seems to be supported on list pages. This is very disappointing. I searched around and found a post from 2016 saying that support for this could be added to content pages at some point, but it doesn’t seem like that ever happened.

My next idea was to just use .Prev and .Next, but in a while loop, checking the returned page’s .Section and comparing it to the current page’s, moving on to the next one (e.g. .Prev.Prev, .Prev.Prev.Prev), and breaking out of the loop when a matching page has been found. So I went off to search how to do a while loop in Go’s templating language, only to find… that while loops don’t even exist!? And apparently neither do break statements…

I suppose I might still be able to do a range over the entire site’s pages, keeping track of pages in variables, checking their sections, etc. to find the PrevInTopSection and NextInTopSection pages that I’m looking for, and then continue the entire loop through the rest of the pages for no reason because I can’t break out of the loop… That might work, but it seems very messy and like I’m having to implement the entire prev/next system myself.

Any ideas?

Am I missing anything here? Is there some simple, elegant solution that somebody could point me to? Thanks.


#2

If “Caring/Feeding” is a single page that refers to all breeds why not include it’s link in the single page template? You can get the next breed in a nested section easily.

If that is not what you want or if “Caring/Feeding” is different from breed to breed you may try creating a filter with range and .GetPage and a variable for a breed’s name and check if the variable equals the title in single.html

But to be honest I think that if “Caring/Feeding” differs from breed to breed you should include that info directly in a breed’s page. Why make a user click a link and not have all relevant info in one page?