Group data by year

Hi all.

I have a yaml file that has the books that I read, like so:

- title: "No Filter: The Inside Story of Instagram"
  author: Sarah Frier
  date: "27.04.2023"
  rating: ★★☆☆☆

- title: "The Shallows: What the Internet Is Doing to Our Brains"
  author: Nicholas Carr
  date: "19.12.2022"
  rating: ★★☆☆☆

I have a page that show the books:

{{ range .Site.Data.read }}
<books>
  <div>{{.date}}</div>
  <div>{{.title}}</div>
  <div><i>{{.author}}</i></div>
  <div>{{.rating}}</div>
</books>
{{ end }}

But now I would like to group the books by year.
I know about {{ range (.Data.Pages.GroupByDate “2006-01”) }}, but how do I combine the two?

Thanks!

First, use a date format (e.g., YYYY-MM-DD) that can be parsed by Go’s time package.

data/read.yaml

- title: "No Filter: The Inside Story of Instagram"
  author: Sarah Frier
  date: 2023-04-27
  rating: ★★☆☆☆
- title: "The Shallows: What the Internet Is Doing to Our Brains"
  author: Nicholas Carr
  date: 2022-12-19
  rating: ★★☆☆☆

Second, we need to create two new slices:

  • A slice of unique years
  • A slice of maps identical to your YAML data, but we add a new key “year”
{{ $years := slice }}
{{ $read := slice }}
{{ range site.Data.read }}
  {{ $year := (time.AsTime .date).Year }}
  {{ $read = $read | append (merge . (dict "year" $year)) }}
  {{ $years = $years | append $year }}
{{ end }}
{{ $years := $years | uniq | sort }}

To examine the $read data structure, place this in your template:

<pre>{{ jsonify (dict "indent" "  ") $read }}</pre>

Finally, we need to range through the slice of years, and display the matching books:

{{ range $years }}
  <h2>{{ . }}</h2>
  {{ range where $read "year" . }}
    Title: {{ .title }}<br>
    Author: {{ .author }}<br>
    Rating: {{ .rating }}<br><br>
  {{ end }}
{{ end }}

2 Likes

Thanks for your quick reply! I will try this.

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.