Custom Sort Hugo Single Pages

Posted on

When building a static website with Hugo, a frequent need is to sort the pages in some way. I’ve seen in the docs and in forum posts how to do that on list pages where you’re iterating through pages with range, but not to do that from a single page template. Here’s how you can change the sort on single pages in order to change which pages .NextPage, .NextInSection and related, point to.

Hugo has a default sort order for pages. Without any interaction from you, pages will be sorted by “Weight”, “Date”, “LinkTitle”, and finally “FilePath” (ref). On list pages (the homepage and _index.html pages of sections) the sort order can be changed by adjusting range. On single pages, which is the template used when viewing an individual page that isn’t an index, there is no range loop present so that can be altered. Here’s how you can do it instead.

It is common for a single template page to use .NextInSection and .PrevInSection like this:

{{ with .NextInSection }}
	<a title="Next page in {{ .Section }}" href="{{ .Permalink }}">Next</a>
{{ end }}

{{ with .PrevInSection }}
	<a title="Previous page in {{ .Section }}" href="{{ .Permalink }}">Previous</a>
{{ end }}

This will only use Hugo’s default sort to create the “timeline” of which page comes after the other. If you don’t like the default sort and you have a small section, setting the weight in each page’s front matter will help as weight is the most important factor in the default sort. Otherwise we can take advantage of Page Methods to change the order.

We can use the .Next and .Prev Page Methods together with a sort function to create a new page order. The sort functions are things like ByTitle, ByLength, or the flexible ByParam. Here’s an example using .ByTitle:

{{ $pages := where site.RegularPages "Section" .Section }}
{{ with $pages.ByTitle.Next . }}
	<a title="Next page in {{ .Section }}" href="{{ .Permalink }}">Next</a>
{{ end }}

{{ with $pages.ByTitle.Prev . }}
	<a title="Previous page in {{ .Section }}" href="{{ .Permalink }}">Previous</a>
{{ end }}

That’s how you can customize sort in a single page template. It’s not as simple as using something like .NextInSection.ByTitle if it existed, but it’s simple enough and works.

edit: I was told that this method works best when used with Hugo v0.59.0 and newer.

comments powered by Disqus
Share
Share