Howto: Custom archive page for all blog posts, per year

Hello all

I have converted my blog to Hugo, from Octopress. Transition went smootly and the only annoyance is that my archives page is showing a nonexisting “Posts” post at the top.

I have added theme/layout/archives/list.html which contains this:

{{ partial "head.html" . }}
<div class="content container">
	<h1>Blog archives</h1>
	{{ range (where .Site.Pages "Type" "post").GroupByDate "2006" }}
	<section class="archive">
		<h2>{{ .Key }}</h2>
		    {{ range .Pages }}
			<li><time>{{ .Date.Format "Jan 2" }}</time>
				<br><a href="{{ .Permalink }}" class="permalink">{{ .Title }}</a>
				{{ if isset .Params "categories" }}
				<br><span class="post-tags">
					<span class="prefix">categories:</span> {{ range .Params.categories }}
						<a href="/categories/{{ . | urlize }}">{{ . }}</a> ·
					{{ end }}
				{{ end }}
				{{ if isset .Params "tags" }}
				<br><span class="post-tags">
					<span class="prefix">tags:</span> {{ range .Params.tags }}
						<a href="/tags/{{ . | urlize }}">{{ . }}</a> ·
					{{ end }}
				{{ end }}
		    {{ end }}
	{{ end }}
{{ partial "foot.html" . }}

I can’t figure out how to remove this “Posts” item.

That’s your posts section page.

Try {{ range (where .Site.Data.Pages "Type" "post").GroupByDate "2006" }}

It should take care of it.

Thanks for quick reply.

I added .Data but it now throws an error

ERROR 2017/06/12 13:18:14 
Error while rendering "section": template: theme/archives/list.html:5:11: 
executing "theme/archives/list.html" at <where .Site.Data.Pag...>: 
error calling where: can't iterate over <nil>

Note that I have content/archives/ (which is empty) - otherwise this page is never generated. Not sure is that correct way to create date-based list of posts, but nothing else seemed to work.

My bad! Doing too many things at the same time .Site.Data.Pages should be .Data.Pages

Yes. If you need to have /archives/ in the URL, that’s the way do it. Hugo does not offer in-built archives.

Let me know if .Data.Pages solved this for you.

Using this:

{{ range (where .Data.Pages "Type" "post").GroupByDate "2006" }}

throws no errors, but also no data appears on the page. Like the range.count is 0. It looks like it’s missing the context what .Data is supposed to be.

Right. This happens because there are no posts under /archives/ and you have this snippet in

What you really want to render is located at

So. Let’s do this a different way.

{{ with .Site.GetPage "section" "post" }}
{{ range .Data.Pages.GroupByDate "2006-01" }}
Archives Title and {{ .Key }} markup here
{{ range .Pages }}
The rest of your markup goes here
{{ end }}
{{ end }}
{{ end }}

This is tested and it should work for you.


Fantastic! That works.

Thanks so much, I learned a lot in this thread.

1 Like

I’m a Hugo beginner. I’m asking this because I’m still learning.

I had the same problem with the dangling ‘post’ entry. I solved it by using range where.

{{ range where .Site.Pages "Section" "post" }}
  {{ range (.Pages.GroupByDate "2006") }}
    -year key
    {{ range (.Pages.GroupByDate "1") }}
      - month key
      {{ range .Pages}}
        {{ .Render "summary" }}
      {{ end }}
    {{ end }}
  {{ end }}
{{ end }}

My question is: are there any reasons not to use this construct? I like it more because I do not have to use .Data which makes it a bit easier for me to comprehend whilst reading.

That works also.

In Hugo there are more than one way of doing things. So I see no reason why you shouldn’t use it.

1 Like