Skip to content
New issue

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

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

Already on GitHub? Sign in 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.

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

No branches or pull requests

2 participants