ventojs / vento

🌬 A template engine for Deno & Node
https://vento.js.org/
MIT License
183 stars 10 forks source link

groupBy filter #11

Closed Brixy closed 1 year ago

Brixy commented 1 year ago

This is a second post today ;-) and probably not a vento issue but a question.

Nunjucks has a groupby filter:

{% for year, pages in pages | groupby("year") %}
…
{% endfor %}

How is it possible to do something comparable in vento using a filter script?

Thanks a lot!

P.S.: Please just close this issue if this is just a JS but not a vento related question.

oscarotero commented 1 year ago

Many Nunjucks filters can be replaced by simple javascript functions. In your example, you can use the Array.sort() function:

{{ for year, pages of pages.sort((a, b) => a.year - b.year) }}
...
{{ /for }}

Or use a pipe if you prefer:

{{ for year, pages of pages |> sort((a, b) => a.year - b.year) }}
...
{{ /for }}

It's also possible to register filters in vento, so you could do something like this:

env.filters.groupby = function (arr, key) {
  return arr.sort((a, b) => a[key] - b[key]);
}

An now you can use it:

{{ for year, pages of pages |> groupby("year") }}
...
{{ /for }}
Brixy commented 1 year ago

Excellent! Thanks a lot.

I forgot how JS-ish vento is.

dogfuntom commented 1 month ago

A sample for Lume:

import { intersect } from '@std/collections'
import { Environment } from 'lume/deps/vento.ts'
site.hooks.vento((vento: Environment) => {
  Object.assign(vento.filters, { intersect })
})

Warning: I stumbled on it by tinkering and thus not sure how idiomatic is it.