Update Note
When this post was originally published, it linked to a dynamic version of the All Posts list page. That page has been retired. Consequently, links to that page have been replaced with a links to a saved static version of that page.
The Challenge
This project is built with Hugo and uses the Minimal Hugo theme.
This post is part of an ongoing effort to tailor the theme over time.
For this post, we’ll look at how to build an automated list of all posts in the /project/content/post/ directory while leaving the existing paginator unaltered.
Hugo allows one list template per section, and since we want to keep the existing paginator, we need to find another way to automatically build that list.
The Process
A web search of the topic didn’t yield any relevant results, so we next turned to asking for direction on Hugo-focused web forums.
A helpful answer came almost immediately, thanks to Bryce Wray. In addition to outlining his approach, he linked to his code and the resulting site map on his webpage.
This article by Kodify.net offered additional guidance for defining filters in Hugo.
Combination, modification, and testing of those techniques formed the basis of the solution for this project.
The Solution
New layout directory and new template file
Since we want list pages for the /project/content/post/ directory to be built using the default list template, we’ll create a separate template in a different directory.
Specifically, we’ll create the new directory /project/layouts/map/ and to that directory we’ll add the file single.html, which contains:
{{ partial "header" . }}
<main>
<div>{{ .Content }}</div>
<h5>{{ len (where .Site.RegularPages "Section" "==" "post") }} total posts</h5>
<h5><a href="/post/">See the paginated list.</a></h5>
<hr>
{{ range where .Site.Pages.ByPublishDate.Reverse "Section" "==" "post" }}
{{ if (ne .Title "Posts") }}
{{ partial "list-item" . }}
{{ end }}
{{ end }}
<hr>
</main>
{{ partial "footer" . }}
Looking more closely:
<h5>{{ len (where .Site.RegularPages "Section" "==" "post") }} total posts</h5>
- provides a count of all pages in the /project/content/post/ directory.
<h5><a href="/post/">See the paginated list.</a></h5>
- creates a link to the original paginated list of the posts in /project/content/post/ directory.
{{ range where .Site.Pages.ByPublishDate.Reverse "Section" "==" "post" }}
- iterates through pages in the /project/content/post/ directory.
{{ if (ne .Title "Posts") }}
- excludes the post list itself (as Wray explains in his answer).
{{ partial "list-item" . }}
- uses the list-item partial to output each iterated page (except the post list itself).
We expect that this could eventually be generalized to create more lists of other content in the same directory by extracting the references to post
into a variable that is passed to the page. For now, the current version meets the needs of the project.
New content directory and content file
With the new layout directory and template file created, we can now create the content directory and content file that will instantiate the page.
Specifically, we’ll create the new directory /project/content/map/ and to that directory we’ll add the file all-posts.md, which (besides frontmatter) contains only the page title, since all other necessary information is contained in the template:
## All Posts
The Result
With that, Hugo can automatically build a page listing all posts in the /project/content/post/ directory .