Note of Caution
The approach detailed in this post has some problems and produces confusing results for subsection list pages.
It was replaced and superceded by the approach used in this post.
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.
Introduction
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.
Objective
In this post we’ll build a new user interface for navigating between list pages.
As of this writing, the list page has right and left arrows that allow navigating to the list pages for earlier and later posts. We’ll keep those, and add a count of the list pages to provide some context, as well as adding a link to the All Posts list page.
We built elements of this in previous posts:
Now, we’ll incorporate those elements into a new working interface for the site.
Building the new navigation interface
Step 1 - Adding the basic structure
Because list pages in Hugo are built with layout files, this will involve updating the Hugo theme’s paginator.html file, which is in the /layouts/partials/ directory.
We’ll add the new features below the existing paginator elements.
To start, we’ll copy the code from prototype 7 of Testing CSS Grid post (removing the -proto7 suffix from element IDs), and add it to the paginator.html file:
<div id="listpage-navigation-container">
<div id="listpage-navigation-panel">
<a id="listpage-navigation-left" href="">Left Navigation</a>
<div id="listpage-navigation-pagexofy">List Page X of Y</div>
<div id="listpage-navigation-allpostlink"><a href="/map/all-posts/">See All Z Posts</a></div>
<a id="listpage-navigation-right" href="">Right Navigation</a>
</div>
</div>
Similarly, we’ll add the CSS from that prototype to the custom.css file in our /static/css/ directory that we created in the Changing the Spacing of Font Awesome Icons in Hugo post:
/* List Page Navigation Interface */
div#listpage-navigation-container {
display: grid;
justify-content: center;
grid-template-columns: minmax(50px, auto);
}
div#listpage-navigation-panel {
display: grid;
grid-template-areas:
"left pagexofy right"
"left allpostlink right";
grid-template-columns: repeat(3, minmax(50px, 300px));
justify-items: stretch;
}
a#listpage-navigation-left {
grid-area: left;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
}
div#listpage-navigation-pagexofy {
grid-area: pagexofy;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
}
div#listpage-navigation-allpostlink {
grid-area: allpostlink;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
}
a#listpage-navigation-right {
grid-area: right;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
}
Step 2 - Incorporating the existing Hugo conditional logic
We’ll integrate the conditional logic from the current paginator.
{{ if or .Paginator.HasPrev .Paginator.HasNext }}
<div id="listpage-navigation-container">
<div id="listpage-navigation-panel">
{{ if .Paginator.HasPrev }}
<a id="listpage-navigation-left" href="">Left Navigation</a>
{{ else }}
<a id="listpage-navigation-left" href="">Beginning</a>
{{ end }}
<div id="listpage-navigation-pagexofy">List Page X of Y</div>
<div id="listpage-navigation-allpostlink"><a href="/map/all-posts/">See All Z Posts</a></div>
{{ if .Paginator.HasNext }}
<a id="listpage-navigation-right" href="">Right Navigation</a>
{{ else }}
<a id="listpage-navigation-right" href="">End</a>
{{ end }}
</div>
</div>
{{ end }}
Step 3 - Incorporating the existing paginator link and page count logic
We’ll integrate the link and page count logic from the current paginator.
{{ if or .Paginator.HasPrev .Paginator.HasNext }}
<div id="listpage-navigation-container">
<div id="listpage-navigation-panel">
{{ if .Paginator.HasPrev }}
<a id="listpage-navigation-left" href="{{ .Paginator.Prev.URL }}" rel="prev">Left Navigation</a>
{{ else }}
<a id="listpage-navigation-left" href="">Beginning</a>
{{ end }}
<div id="listpage-navigation-pagexofy">List page {{ .Paginator.PageNumber }} of {{ .Paginator.TotalPages }}.</div>
<div id="listpage-navigation-allpostlink"><a href="/map/all-posts/">See All Z Posts</a></div>
{{ if .Paginator.HasNext }}
<a id="listpage-navigation-right" href="{{ .Paginator.Next.URL }}" rel="next">Right Navigation</a>
{{ else }}
<a id="listpage-navigation-right" href="">End</a>
{{ end }}
</div>
</div>
{{ end }}
Step 4 - Incorporating the section page count logic
We’ll integrate logic for counting the total number of pages in a section.
{{ if or .Paginator.HasPrev .Paginator.HasNext }}
<div id="listpage-navigation-container">
<div id="listpage-navigation-panel">
{{ if .Paginator.HasPrev }}
<a id="listpage-navigation-left" href="{{ .Paginator.Prev.URL }}" rel="prev">Left Navigation</a>
{{ else }}
<a id="listpage-navigation-left" href="">Beginning</a>
{{ end }}
<div id="listpage-navigation-pagexofy">List page {{ .Paginator.PageNumber }} of {{ .Paginator.TotalPages }}.</div>
<div id="listpage-navigation-allpostlink"><a href="/map/all-posts/">See all {{ .Paginator.TotalNumberOfElements }} posts.</a></div>
{{ if .Paginator.HasNext }}
<a id="listpage-navigation-right" href="{{ .Paginator.Next.URL }}" rel="next">Right Navigation</a>
{{ else }}
<a id="listpage-navigation-right" href="">End</a>
{{ end }}
</div>
</div>
{{ end }}
Step 5 - Incorporating the Font Awesome icons
We’ll integrate the Font Awesome icons from the current paginator.
{{ if or .Paginator.HasPrev .Paginator.HasNext }}
<div id="listpage-navigation-container">
<div id="listpage-navigation-panel">
{{ if .Paginator.HasPrev }}
<a id="listpage-navigation-left" href="{{ .Paginator.Prev.URL }}" rel="prev">
<i class="fa fa-arrow-left fa-3x"></i>
</a>
{{ else }}
<a id="listpage-navigation-left" href="">Beginning</a>
{{ end }}
<div id="listpage-navigation-pagexofy">List page {{ .Paginator.PageNumber }} of {{ .Paginator.TotalPages }}.</div>
<div id="listpage-navigation-allpostlink"><a href="/map/all-posts/">See all {{ .Paginator.TotalNumberOfElements }} posts.</a></div>
{{ if .Paginator.HasNext }}
<a id="listpage-navigation-right" href="{{ .Paginator.Next.URL }}" rel="next">
<i class="fa fa-arrow-right fa-3x"></i>
</a>
{{ else }}
<a id="listpage-navigation-right" href="">End</a>
{{ end }}
</div>
</div>
{{ end }}
Step 6 - Incorporating theme styling
We’ll integrate element class declarations from the current paginator to produce consistent styling.
{{ if or .Paginator.HasPrev .Paginator.HasNext }}
<div id="listpage-navigation-container">
<div id="listpage-navigation-panel">
{{ if .Paginator.HasPrev }}
<a id="listpage-navigation-left" class="icon pages-icon" href="{{ .Paginator.Prev.URL }}" rel="prev">
<i class="fa fa-arrow-left fa-3x"></i>
</a>
{{ else }}
<a id="listpage-navigation-left" class="icon pages-icon" href="">Beginning</a>
{{ end }}
<div id="listpage-navigation-pagexofy">List page {{ .Paginator.PageNumber }} of {{ .Paginator.TotalPages }}.</div>
<div id="listpage-navigation-allpostlink"><a href="/map/all-posts/">See all {{ .Paginator.TotalNumberOfElements }} posts.</a></div>
{{ if .Paginator.HasNext }}
<a id="listpage-navigation-right" class="icon pages-icon" href="{{ .Paginator.Next.URL }}" rel="next">
<i class="fa fa-arrow-right fa-3x"></i>
</a>
{{ else }}
<a id="listpage-navigation-right" class="icon pages-icon" href="">End</a>
{{ end }}
</div>
</div>
{{ end }}
Step 7 - Commenting out the previous paginator code
Now that we’ve built a new interface for list page navigation we can comment out the code for the previous version.
Conclusion
This improved interface is better suited to the current needs of the project. (At the time of this writing it can be seen at the bottom of the list page, just above the header.)
There are still several areas for improvement:
- The Bootstrap CSS distorts the layout for really small viewports.
- The Bootstrap CSS ignores or resets every HTML tag type we tested except anchor elements, so to preserve formatting the “Beginning” and “End” text are tagged as anchors with empty hyperlinks, which is not ideal.
- The paginator allpostlink is hardcoded to /map/all-posts/, which will need to be changed if the paginator is to be used for other sections.