Lists of content in Hugo
What is a list page template?
A list page template is a template used to render multiple pieces of content in a single HTML page. The exception to this rule is the homepage, which is still a list but has its own dedicated template.
Hugo uses the term list in its truest sense; i.e. a sequential arrangement of material, especially in alphabetical or numerical order. Hugo uses list templates on any output HTML page where content is traditionally listed:
For template lookup order, see Template Lookup.
The idea of a list page comes from the hierarchical mental model of the web and is best demonstrated visually:
List defaults
Default templates
Since section lists and taxonomy lists (N.B., not taxonomy terms lists) are both lists with regards to their templates, both have the same terminating default of _default/list.html
or themes/<THEME>/layouts/_default/list.html
in their lookup order. In addition, both section lists and taxonomy lists have their own default list templates in _default
.
See Template Lookup Order for the complete reference.
Add content and front matter to list pages
Since v0.18, everything in Hugo is a Page
. This means list pages and the homepage can have associated content files (i.e. _index.md
) that contain page metadata (i.e., front matter) and content.
This new model allows you to include list-specific front matter via .Params
and also means that list templates (e.g., layouts/_default/list.html
) have access to all page variables.
Example project directory
The following is an example of a typical Hugo project directory’s content:
.
...
├── content
| ├── posts
| | ├── _index.md
| | ├── post-01.md
| | └── post-02.md
| └── quote
| | ├── quote-01.md
| | └── quote-02.md
...
Using the above example, let’s assume you have the following in content/posts/_index.md
:
---
title: My Go Journey
date: 2017-03-23
publishdate: 2017-03-24
---
I decided to start learning Go in March 2017.
Follow my journey through this new blog.
You can now access this _index.md
’s’ content in your list template:
{{ define "main" }}
<main>
<article>
<header>
<h1>{{ .Title }}</h1>
</header>
<!-- "{{ .Content }}" pulls from the Markdown content of the corresponding _index.md -->
{{ .Content }}
</article>
<ul>
<!-- Ranges through content/posts/*.md -->
{{ range .Pages }}
<li>
<a href="{{ .RelPermalink }}">{{ .Date.Format "2006-01-02" }} | {{ .LinkTitle }}</a>
</li>
{{ end }}
</ul>
</main>
{{ end }}
This above will output the following HTML:
<!--top of your baseof code-->
<main>
<article>
<header>
<h1>My Go Journey</h1>
</header>
<p>I decided to start learning Go in March 2017.</p>
<p>Follow my journey through this new blog.</p>
</article>
<ul>
<li><a href="/posts/post-01/">Post 1</a></li>
<li><a href="/posts/post-02/">Post 2</a></li>
</ul>
</main>
<!--bottom of your baseof-->
List pages without _index.md
You do not have to create an _index.md
file for every list page (i.e. section, taxonomy, taxonomy terms, etc) or the homepage. If Hugo does not find an _index.md
within the respective content section when rendering a list template, the page will be created but with no {{ .Content }}
and only the default values for .Title
etc.
Using this same layouts/_default/list.html
template and applying it to the quotes
section above will render the following output. Note that quotes
does not have an _index.md
file to pull from:
<!--baseof-->
<main>
<article>
<header>
<!-- Hugo assumes that .Title is the name of the section since there is no _index.md content file from which to pull a "title:" field -->
<h1>Quotes</h1>
</header>
</article>
<ul>
<li><a href="https://example.org/quote/quotes-01/">Quote 1</a></li>
<li><a href="https://example.org/quote/quotes-02/">Quote 2</a></li>
</ul>
</main>
<!--baseof-->
Example list templates
Section template
This list template has been modified slightly from a template originally used in spf13.com. It makes use of partial templates for the chrome of the rendered page rather than using a base template. The examples that follow also use the content view templates li.html
or summary.html
.
{{ partial "header.html" . }}
{{ partial "subheader.html" . }}
<main>
<div>
<h1>{{ .Title }}</h1>
<ul>
<!-- Renders the li.html content view for each content/posts/*.md -->
{{ range .Pages }}
{{ .Render "li" }}
{{ end }}
</ul>
</div>
</main>
{{ partial "footer.html" . }}
Taxonomy template
{{ define "main" }}
<main>
<div>
<h1>{{ .Title }}</h1>
<!-- ranges through each of the content files associated with a particular taxonomy term and renders the summary.html content view -->
{{ range .Pages }}
{{ .Render "summary" }}
{{ end }}
</div>
</main>
{{ end }}
Sort content
By default, Hugo sorts page collections by:
- Page weight
- Page date (descending)
- Page linkTitle, falling back to page title
- Page file path if the page is backed by a file
Change the sort order using any of the methods below.
- .ByDate
- Returns the given page collection sorted by date in ascending order.
- .ByExpiryDate
- Returns the given page collection sorted by expiration date in ascending order.
- .ByLanguage
- Returns the given page collection sorted by language in ascending order.
- .ByLastmod
- Returns the given page collection sorted by last modification date in ascending order.
- .ByLength
- Returns the given page collection sorted by content length in ascending order.
- .ByLinkTitle
- Returns the given page collection sorted by link title in ascending order, falling back to title if link title is not defined.
- .ByParam
- Returns the given page collection sorted by the given parameter in ascending order.
- .ByPublishDate
- Returns the given page collection sorted by publish date in ascending order.
- .ByTitle
- Returns the given page collection sorted by title in ascending order.
- .ByWeight
- Returns the given page collection sorted by weight in ascending order.
- .Reverse
- Returns the given page collection in reverse order.
Group content
Group your content by field, parameter, or date using any of the methods below.
- .GroupBy
- Returns the given page collection grouped by the given field in ascending order.
- .GroupByDate
- Returns the given page collection grouped by date in descending order.
- .GroupByExpiryDate
- Returns the given page collection grouped by expiration date in descending order.
- .GroupByLastmod
- Returns the given page collection grouped by last modification date in descending order.
- .GroupByParam
- Returns the given page collection grouped by the given parameter in ascending order.
- .GroupByParamDate
- Returns the given page collection grouped by the given date parameter in descending order.
- .GroupByPublishDate
- Returns the given page collection grouped by publish date in descending order.
- .Reverse
- Returns the given page collection in reverse order.
Filtering and limiting lists
Sometimes you only want to list a subset of the available content. A common is to only display posts from main sections on the blog’s homepage.
See the documentation on where
and
first
for further details.