Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

group_by_exp fails with object as input #785

Closed
theonlypwner opened this issue Jan 3, 2025 · 4 comments
Closed

group_by_exp fails with object as input #785

theonlypwner opened this issue Jan 3, 2025 · 4 comments

Comments

@theonlypwner
Copy link

theonlypwner commented Jan 3, 2025

In Jekyll, it is possible to do

{%- assign tags_by_size = site.tags | group_by_exp: 'tag', 'tag[1].size' | sort: 'name' | reverse -%}
{%- for tags_with_size in tags_by_size -%}
{%- for tag in tags_with_size.items -%}
{%- assign tag_name = tag[0] -%}
<!-- ... -->
{{ tag_name }} <sup>{{ tags_with_size.name }}</sup> <!-- tag name and count -->
<!-- ... -->
{%- for post in tag[1] %}
<!-- render each post with this tag -->
<!-- ... -->

However, in liquidjs, collections.postsByTag | group_by_exp: 'tag', 'tag[1].size' (where collections.postsByTag in Eleventy is in the same format as site.tags in Jekyll) just ends up being [ { name: undefined, items: [ [Object] ] } ]

Running collections.postsByTag through Object.entries makes this filter work properly.

This came up while migrating from Jekyll to Eleventy, but I will probably end up reimplementing this functionality, so I might not need it in the end, but I am reporting this missing functionality here.

@harttle
Copy link
Owner

harttle commented Jan 4, 2025

I guess the issue is about tag[1].size

Do we know the structure of tag here?

@theonlypwner
Copy link
Author

site.tags or collections.postsByTag is an object that maps tag names to an array of posts, like {tag0: [post0, post1], tag1: [post1, post2]}, so tag would be an array of size 2, like ["tag0", [post0, post1]]

github-actions bot pushed a commit that referenced this issue Jan 4, 2025
## [10.20.1](v10.20.0...v10.20.1) (2025-01-04)

### Bug Fixes

* break/continue stops whole template, [#783](#783) ([5f1a4cf](5f1a4cf))
* enumerate plain objects in where/where_exp, [#785](#785) ([#788](#788)) ([25ef104](25ef104))
* preserveTimezones support for RFC2822 date, [#784](#784) ([59cf3c0](59cf3c0))
@harttle
Copy link
Owner

harttle commented Jan 5, 2025

Please try 10.20.1, let me know if there's still any issue. I created a test case for this issue:

it('group_by_exp fails with object as input #785', () => {
const site = {
tags: {
CPP: [ 'page0' ],
PHP: [ 'page0', 'page2' ],
JavaScript: [ 'page1', 'page2', 'page3' ],
CSharp: [ 'page2', 'page4' ]
}
}
const tpl = `
{%- assign tags_by_size = site.tags | group_by_exp: 'tag', 'tag[1].size' | sort: 'name' | reverse -%}
{%- for tags_with_size in tags_by_size -%}
{%- for tag in tags_with_size.items -%}
{%- assign tag_name = tag[0] %}
{{ tag_name }} <sup>{{ tags_with_size.name }}</sup> Posts:
{%- for post in tag[1] -%}{{post}},{%- endfor -%}
{%- endfor -%}
{%- endfor -%}
`
const engine = new Liquid()
const html = engine.parseAndRenderSync(tpl, { site })
expect(html).toEqual(`
JavaScript <sup>3</sup> Posts:page1,page2,page3,
PHP <sup>2</sup> Posts:page0,page2,
CSharp <sup>2</sup> Posts:page2,page4,
CPP <sup>1</sup> Posts:page0,`)
})

@theonlypwner
Copy link
Author

It seems to be working in 10.20.1.

In 10.20.0, collections.postsByTag | entries | group_by_exp: 'tag', 'tag[1].size' | ... was the workaround. I had a custom entries filter that calls Object.entries.

In 10.20.1, collections.postsByTag | group_by_exp: 'tag', 'tag[1].size' | ... generates the same output.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants