I have a list of objects. These objects have a date attribute. I want to group by year.
Something along the lines of the following would be nice.
for year, posts in collections.post | groupby("date.year")
But it begs the question how to deal with transforms that need to happen before the grouping.
Is there a way to use groupby like this?
Oh man, this is exactly the problem I'm trying to solve.
@tcurdt This may help: https://stackoverflow.com/questions/12764291/jinja2-group-by-month-year
@mattradford That's exactly what I was referring to with date.year above ;) Unfortunately that does not work (for me).
Looking at the underlying groupBy code here: https://github.com/mozilla/nunjucks/blob/master/nunjucks/src/lib.js#L172
It takes a function, so you can write a generic getPath function that returns a function to get the value you want to group on. Just verified that this works. Here's my getPath:
const getPath = (path) => {
const parts = path.split('.');
return (value, i) => {
let o = value;
for (const p of parts) {
if (o == null) {
return;
}
o = o[p];
}
return o;
};
}
@justinfagnani The function is straight forward - but the question is how this should look like in the expression.
The depends on how you get the function as data into your template. I'm using eleventy, and putting the function into a docs object. My template looks like:
{% for group, examples in collections.examples | groupby(docs.getPath('data.group')) %}
...
{% endfor %}
This is a filter I'm using for Nunjucks in Eleventy:
groupByEx: function (arr, key) {
const result = {};
arr.forEach(item => {
const keys = key.split('.');
const value = keys.reduce((object, key) => object[key], item);
(result[value] || (result[value] = [])).push(item);
});
return result;
}
Sample (actual) usage:
for categoryName, articles in productArticles | groupByEx("data.categoryName")
Acknowledgement: Code based on whatterz/includes.js
@anaurelian that's already pretty slick - but it would need a special case for dates I guess.
Most helpful comment
This is a filter I'm using for Nunjucks in Eleventy:
Sample (actual) usage:
for categoryName, articles in productArticles | groupByEx("data.categoryName")Acknowledgement: Code based on whatterz/includes.js