First of all, if you don’t know about data files, you may want to start reading from data files in hugo. This post is about a solution for a very particular problem. How can we use “group by” for the data from data files?
Let me clarify with an example. I was creating a single page Hugo theme for generating my Resume using data files. You can find the project here: Resume A4 or the blog post. So, we have a data file called experience.yaml
:
- name: Software Developer
company: Uber
date: 2019 - Present
- name: Junior Software Developer
company: Uber
date: 10.2018 - Present
- name: Intern
company: Netflix
date: 11.2016 - 07.2017
We don’t want to add a new big heading for each position update in the same company. We want to add the company name for once and add positions under the company name. Just like how Linkedin groups “Experience” section in user profile. So, we need to group the first two items since both experiences come from the same company.
Now, this is how you can group data by a key in Hugo. The key in our example is “company”.
First, create a slice that contains all the unique names we need.
{{ $companies := slice }}
{{ range .Site.Data.experience }}
{{ $companies = $companies | append .company }}
{{ end }}
{{ $companies = uniq $companies }}
Then, we need to create a nested loop. The outer loop should loop through the slice that contains unique names and the inner loop should loop through the data file with a where condition. Where “group-name” = “name-from-the-outer-loop”.
{{ range $companies }}
{{ $company := . }}
<h3 class="item-title">{{ $company }}</h3>
{{ range where $.Site.Data.experience "company" $company }}
{{ .name }} {{ .date }}
{{ .details | markdownify }}
{{ end }}
{{ end }}
Update: Even though the example above is correct and grouping works fine, I’ve found a flaw in my solution. When we group by company, we don’t consider the time. One may work for a company (X) for a while, had different titles, or roles then leave. Work somewhere else for a while. Then again, get a new job in that company X. This case must be very rare but still it might happen. Here is an example:
- company: Uber
roles:
- role: Data Scientist
date: 10.2020 - Present
- company: Google
roles:
- role: Senior Software Developer
details: >
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus ornare sollicitudin fringilla.
Aenean nec volutpat arcu. Maecenas quis tempus risus.
date: "06.2019 - 10.2020"
- role: Junior Software Developer
date: 10.2018 - 06.2019
- company: Uber
roles:
- role: Driver
date: 2017 - 10.2018
details: Lorem ipsum dolor sit amet
When we group by company, we’ll group Uber roles too but we shouldn’t. That’s why I removed the grouping part from my project and entered roles as an array in the YAML file. Everything is simpler and better now. One key learning here, the structure we store the data really matters, even in small weekend projects like this.