Skip to content

Commit

Permalink
Fix: respect parameter order when using "for ... reversed" (#231)
Browse files Browse the repository at this point in the history
* fix: spelling

* fix: respect param order for reversed

* docs: add for-reversed order details

* perf: improve performance by 4x by simplified parseFile

BREAKING CHANGES:
- previously deprecated `getTemplate()` and `getTemplateSync()` not no longer supported
- `opts` no longer support dynamic set in `parseFile()`, `renderFile()` arguments

* perf: parse filenames in parse() insteadof render()

* docs: update description of LiquidJS

Co-authored-by: harttle <[email protected]>
  • Loading branch information
stedman and harttle committed Sep 30, 2021
1 parent 9012133 commit fb787e8
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 9 deletions.
30 changes: 28 additions & 2 deletions docs/source/tags/for.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ There's a `forloop` object available inside `for` loops. It's used to indicate t
The `forloop.first`, `forloop.last` and `forloop.length` property:

Input
```
```liquid
{% for i in (1..5) %}
{%- if forloop.first == true -%} First
{%- elsif forloop.last == true -%} Last
Expand All @@ -116,7 +116,7 @@ Input
```

Output
```
```text
First
5
5
Expand Down Expand Up @@ -218,3 +218,29 @@ Output
```text
6 5 4 3 2 1
```

When used with additional parameters, order is important. Leading with `reversed` reverses the order of the loop before executing the other parameters.

Input
```liquid
{% for i in (1..8) reversed limit: 4 %}
{{ i }}
{% endfor %}
```

Output
```text
8 7 6 5
```

Input
```liquid
{% for i in (1..8) limit: 4 reversed %}
{{ i }}
{% endfor %}
```

Output
```text
4 3 2 1
```
7 changes: 5 additions & 2 deletions src/builtin/tags/for.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default {

this.variable = variable.content
this.collection = collection
this.hash = new Hash(toknenizer.remaining())
this.hash = new Hash(tokenizer.remaining())
this.templates = []
this.elseTemplates = []

Expand Down Expand Up @@ -46,9 +46,12 @@ export default {
const hash = yield this.hash.render(ctx)
const offset = hash.offset || 0
const limit = (hash.limit === undefined) ? collection.length : hash.limit
const reversedIndex = Reflect.ownKeys(hash).indexOf('reversed')

// reverse collection before slicing if 'reversed' is 1st parameter
if (reversedIndex === 0) collection.reverse()
collection = collection.slice(offset, offset + limit)
if ('reversed' in hash) collection.reverse()
if (reversedIndex > 0) collection.reverse()

const scope = { forloop: new ForloopDrop(collection.length) }
ctx.push(scope)
Expand Down
11 changes: 6 additions & 5 deletions test/integration/builtin/tags/for.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,25 +207,26 @@ describe('tags/for', function () {
})
})

describe('reverse', function () {
describe('reversed', function () {
it('should support for reversed in the last position', async function () {
const src = '{% for i in (1..5) limit:2 reversed %}{{ i }}{% endfor %}'
const src = '{% for i in (1..8) limit:2 reversed %}{{ i }}{% endfor %}'
const html = await liquid.parseAndRender(src, scope)
return expect(html).to.equal('21')
})

it('should support for reversed in the first position', async function () {
const src = '{% for i in (1..5) reversed limit:2 %}{{ i }}{% endfor %}'
const src = '{% for i in (1..8) reversed limit:2 %}{{ i }}{% endfor %}'
const html = await liquid.parseAndRender(src, scope)
return expect(html).to.equal('21')
return expect(html).to.equal('87')
})

it('should support for reversed in the middle position', async function () {
const src = '{% for i in (1..5) offset:2 reversed limit:4 %}{{ i }}{% endfor %}'
const src = '{% for i in (1..8) offset:2 reversed limit:3 %}{{ i }}{% endfor %}'
const html = await liquid.parseAndRender(src)
return expect(html).to.equal('543')
})
})

describe('sync', function () {
it('should support sync', function () {
const src = '{% for i in (1..5) %}{{i}}{%endfor%}'
Expand Down

0 comments on commit fb787e8

Please sign in to comment.