How to customise list pages
Hugo’s default list page shows an un-ordered list with links to each blog post. I want to change this to look better.
I want to create a template list page that displays the
- Featured image
- Post title, and
- Tags
and that when you click on a Tag (or Category) it takes you to a list page showing a list of all posts with that Tag (or Category)
1. Create a blank page to hold the lists
Create a file layouts/blog/list.html
and insert the following code
{{ define "main" }}
<div class="container">
</div>
{{ end }}
In term
Navigate to http://localhost:1313/blog/ - the list of blog posts has disappeared meaning that this page is being displayed correctly.
2. Create a postcard that can be used in the list pages
Rather than adding lots of code to list.html - we’re going to add a widget that we can reference.
Create and open the file layouts/partials/widgets/postcard.html
adding
{{ $featuredImageUrl := .Params.featuredImageUrl }}
{{ $featuredAltText := .Params.featuredImageAltText }}
{{ $permalink := .Permalink }}
<div class="card">
<div class="card-image">
<figure class="image is-4by3">
{{ with .Params.featuredImageUrl }}
<a href="{{ $permalink }}"><img src="{{ $featuredImageUrl }}" alt="{{ $featuredAltText }}"></a>
{{ end }}
</figure>
</div>
<div class="card-content">
<a class="title is-5" href="{{ $permalink}}">{{ .Title }}</a>
{{ with .Params.tags }}
<p class="is-size-7 has-text-grey-light mt-1">
{{ range . }}
<i class="fas fa-tag"></i>
{{ $href := print (absURL "tags/") (urlize .) }}
<a href="{{ $href }}">{{ . }}</a>
{{ end }}
</p>
{{ end }}
</div>
</div>
This code does a couple of things, it
- Pulls the featured image & title from each post and inserts them into the post card
- Adds the tags in each post as clickable links
3. Edit the list pages to show post cards
Edit layouts/blog/list.html
adding
{{ define "main" }}
<div class="container pt-3 pl-1 pr-1 pb-3">
<h1 class="title ">{{ .Title }}</h1>
<div class="columns is-multiline mt-2">
{{ range .Paginator.Pages.ByPublishDate.Reverse }}
<div class="column is-one-third">
{{ partial "widgets/postcard.html" . }}
</div>
{{ end }}
</div>
</div>
{{ end }}
Navigate to http://localhost:1313/blog/
, your page should look something like this

Please note I’ve created three blog posts which show up here on the list page.
There are some great articles on pagination in Hugo uch as this, this, but given I’m using Bulma then PaksTech solution works perfectly.
The default pagination in Hugo is to list 10 items per page. You can change this in config.toml
paginate = 6
Create and open partials/widgets/paginantion.html
and add the following
{{ $pag := $.Paginator }}
{{ if gt $pag.TotalPages 1 }}
<nav class="pagination">
<ul class="pagination-list">
{{ with $pag.First }}
<li>
<a href="{{ .URL }}" class="pagination-link" {{ if not $pag.HasPrev }} disabled{{ end }} aria-label="First"><span aria-hidden="true">««</span></a>
</li>
{{ end }}
<li>
<a href="{{ if $pag.HasPrev }}{{ $pag.Prev.URL }}{{ end }}" class="pagination-link" {{ if not $pag.HasPrev }} disabled{{ end }} aria-label="Previous"><span aria-hidden="true">«</span></a>
</li>
{{ $ellipsed := false }}
{{ $shouldEllipse := false }}
{{ range $pag.Pagers }}
{{ $right := sub .TotalPages .PageNumber }}
{{ $showNumber := or (le .PageNumber 3) (eq $right 0) }}
{{ $showNumber := or $showNumber (and (gt .PageNumber (sub $pag.PageNumber 2)) (lt .PageNumber (add $pag.PageNumber 2))) }}
{{ if $showNumber }}
{{ $ellipsed = false }}
{{ $shouldEllipse = false }}
{{ else }}
{{ $shouldEllipse = not $ellipsed }}
{{ $ellipsed = true }}
{{ end }}
{{ if $showNumber }}
<li><a class="pagination-link {{ if eq . $pag }}is-current{{ end }}" href="{{ .URL }}">{{ .PageNumber }}</a></li>
{{ else if $shouldEllipse }}
<li class="pagination-link" disabled><span aria-hidden="true"> … </span></li>
{{ end }}
{{ end }}
<li>
<a href="{{ if $pag.HasNext }}{{ $pag.Next.URL }}{{ end }}" class="pagination-link" {{ if not $pag.HasNext }}disabled{{ end }} aria-label="Next"><span aria-hidden="true">»</span></a>
</li>
{{ with $pag.Last }}
<li>
<a href="{{ .URL }}" class="pagination-link" {{ if not $pag.HasNext }}disabled{{ end }} aria-label="Last"><span aria-hidden="true">»»</span></a>
</li>
{{ end }}
</ul>
</nav>
{{ end }}
To use this code, you need to add the following to the list template page
{{ partial "widgets/pagination.html" . }}
Then open and edit layouts/blog/list.html
to read
{{ define "main" }}
<div class="container pt-3 pl-1 pr-1 pb-3">
<h1 class="title ">{{ .Title }}</h1>
<div class="columns is-multiline mt-2">
{{ range .Paginator.Pages.ByPublishDate.Reverse }}
<div class="column is-one-third">
{{ partial "widgets/postcard.html" . }}
</div>
{{ end }}
</div>
<div class="columns is-centered mt-2">
<div class="column is-narrow">
{{ partial "widgets/pagination.html" . }}
</div>
</div>
</div>
{{ end }}
If you have enough blog posts, you will see the pagination show on all list pages with more the (in this case) 6 posts, such as this one below

Open and edit config.toml
and add the following
[menu]
...
[[menu.taxonomy]]
name = "Tags"
url = "/tags"
[[menu.taxonomy]]
name = "Categories"
url = "/categories"
Open and edit partials/footer.html
and add the following
This code in the footer adds links to the static pages (About, Contact and Privacy) as well as two list pages of tags and categories.
The footer now looks like this

And if you click on the link to ‘Categories’ you see this

Useful Links