This post refers to a legacy version of Siteleaf.
Following sort
and where
, this Advanced Liquid post introduces another handy new filter to Siteleaf: group_by
.
As the name suggests, this filter allows you to group your content by a certain property.
For example, here’s how we could group all posts by year published:
{% assign posts_by_year = site.posts | group_by:"year" %}
You can group by any property like date, title, slug, even metadata and taxonomy. Here are a few real-world examples you may want to apply to your theme.
Group posts by author
With multiple authors on our blog, it may be a good idea to group together posts by each author. So let’s do that.
Starting with site.posts
(all posts within our site), we can apply the group_by
filter with author
as the parameter:
{% assign posts_by_author = site.posts | group_by:"author" %}
Behind the scenes, posts are collected into an array which looks something like this:
[
{"name": "Skylar Challand", "items": [...]},
{"name": "Larry Fox", "items": [...]},
...
]
The property (in this case author
) can be accessed by name
and matching posts are grouped under items
. Knowing that, we can display our grouped posts like this:
{% for author in posts_by_author %}
<dt>{{author.name}}</dt>
{% for post in author.items %}
<dd><a href="{{post.url}}">{{post.title}}</a></dd>
{% endfor %}
{% endfor %}
Tip: To sort our authors alphabetically we could also apply sort
to our group:
{% assign posts_by_author = site.posts | group_by:"author" | sort:"name" %}
Group posts by metadata
group_by
also works on metadata and taxonomy. For example, here’s how we could group posts by color:
{% assign posts_by_color = site.pages | group_by:"meta.color" %}
Our grouped array will look something like this:
[
{"name": "red", "items": [...]},
{"name": "blue", "items": [...]},
...
]
Archive page
Grouping posts by year is a common pattern on archive pages. Since Siteleaf already generates archive pages for us, we can easily sprinkle in group_by
and have a beautiful blog archive in minutes.
First, let’s group our posts by year:
{% assign posts_by_year = posts | group_by:"year" %}
Note: We are using posts
in this case rather than site.posts
because we only want posts relative to this page (but either could work).
Now we can display our grouped posts:
{% for year in posts_by_year %}
<h2>{{year.name}}</h2>
<ul>
{% for post in year.items %}
<li><a href="{{post.url}}">{{post.title}}</a></li>
{% endfor %}
</ul>
{% endfor %}
Extra credit: We could take this a step further and do a multi-level group, showing posts by year AND month:
{% for year in posts_by_year %}
<h2>{{year.name}}</h2>
{% assign posts_by_month = year.items | group_by:"month" %}
{% for month in posts_by_month %}
<h3>{{month.items.first.date | date:"%B"}}</h3>
<ul>
{% for post in month.items %}
<li><a href="{{post.url}}">{{post.title}}</a></li>
{% endfor %}
</ul>
{% endfor %}
{% endfor %}
In case you’re wondering, %B
gives us the month name (e.g. “April”) from a date. For full documentation see our date formatting guide.
Until next time, happy coding!
Follow @siteleaf and stay tuned for more Advanced Liquid.