feat: support offset:continue, see #439

This commit is contained in:
Harttle
2022-01-20 00:12:18 +08:00
committed by Harttle
parent 388d0fbbc4
commit 8c27a84059
4 changed files with 144 additions and 34 deletions
+62 -20
View File
@@ -66,17 +66,17 @@ Causes the loop to stop iterating when it encounters the `break` tag.
Input
```liquid
{% for i in (1..5) %}
{% if i == 4 %}
{%- if i == 4 -%}
{% break %}
{% else %}
{%- else -%}
{{ i }}
{% endif %}
{%- endif -%}
{% endfor %}
```
Output
```text
1 2 3
123
```
### continue
@@ -86,17 +86,17 @@ Causes the loop to skip the current iteration when it encounters the `continue`
Input
```liquid
{% for i in (1..5) %}
{% if i == 4 %}
{% continue %}
{% else %}
{%- if i == 4 -%}
{%- continue -%}
{%- else -%}
{{ i }}
{% endif %}
{%- endif -%}
{% endfor %}
```
Output
```text
1 2 3 5
1235
```
### forloop
@@ -152,15 +152,15 @@ Limits the loop to the specified number of iterations.
Input
```liquid
<!-- if array = [1,2,3,4,5,6] -->
<!-- for array = [1,2,3,4,5,6] -->
{% for item in array limit:2 %}
{{ item }}
{{- item -}}
{% endfor %}
```
Output
```text
1 2
12
```
### offset
@@ -169,15 +169,57 @@ Begins the loop at the specified index.
Input
```liquid
<!-- if array = [1,2,3,4,5,6] -->
<!-- for array = [1,2,3,4,5,6] -->
{% for item in array offset:2 %}
{{ item }}
{{- item -}}
{% endfor %}
```
Output
```text
3 4 5 6
3456
```
#### offset:continue
{% since %}v9.33.0{% endsince %}
Offset value can be `continue` to continue previous loop. For example:
Input
```liquid
<!-- for array = [1,2,3,4,5,6] -->
{% for item in array limit:2 %}
{{- item -}}
{% endfor%}
{% for item in array offset:continue %}
{{- item -}}
{% endfor%}
```
Output
```text
12
3456
```
For the same variable name (`"item"` in this case) and same collection (`"array"` in this case), there's one position record. That means you can start a new loop with a different variable name:
Input
```liquid
<!-- for array = [1,2,3,4,5,6] -->
{% for item in array limit:2 %}
{{- item -}}
{% endfor%}
{% for item2 in array offset:continue %}
{{- item2 -}}
{% endfor%}
```
Output
```text
12
123456
```
### range
@@ -187,19 +229,19 @@ Defines a range of numbers to loop through. The range can be defined by both lit
Input
```liquid
{% for i in (3..5) %}
{{ i }}
{% endfor %}
{{- i -}}
{% endfor-%}
{% assign num = 4 %}
{% for i in (1..num) %}
{{ i }}
{{- i -}}
{% endfor %}
```
Output
```text
3 4 5
1 2 3 4
345
1234
```
### reversed
+56 -14
View File
@@ -49,17 +49,17 @@ The collection is empty.
输入
```liquid
{% for i in (1..5) %}
{% if i == 4 %}
{%- if i == 4 -%}
{% break %}
{% else %}
{%- else -%}
{{ i }}
{% endif %}
{%- endif -%}
{% endfor %}
```
输出
```text
1 2 3
123
```
### continue
@@ -69,17 +69,17 @@ The collection is empty.
输入
```liquid
{% for i in (1..5) %}
{% if i == 4 %}
{% continue %}
{% else %}
{%- if i == 4 -%}
{%- continue -%}
{%- else -%}
{{ i }}
{% endif %}
{%- endif -%}
{% endfor %}
```
输出
```text
1 2 3 5
1235
```
### forloop
@@ -137,13 +137,13 @@ index index0 rindex rindex0
```liquid
<!-- if array = [1,2,3,4,5,6] -->
{% for item in array limit:2 %}
{{ item }}
{{- item -}}
{% endfor %}
```
输出
```text
1 2
12
```
### offset
@@ -152,15 +152,57 @@ index index0 rindex rindex0
输入
```liquid
<!-- if array = [1,2,3,4,5,6] -->
<!-- for array = [1,2,3,4,5,6] -->
{% for item in array offset:2 %}
{{ item }}
{{- item -}}
{% endfor %}
```
输出
```text
3 4 5 6
3456
```
#### offset:continue
{% since %}v9.33.0{% endsince %}
`offset` 的值可以是 `continue`,用来继续上一次循环。例如:
输入
```liquid
<!-- for array = [1,2,3,4,5,6] -->
{% for item in array limit:2 %}
{{- item -}}
{% endfor%}
{% for item in array offset:continue %}
{{- item -}}
{% endfor%}
```
输出
```text
12
3456
```
对同样的变量名和集合名(这个例子中是 `"item-array"`),存在唯一的位置记录。也就是说用新的变量名就可以开启一个新的循环:
输入
```liquid
<!-- for array = [1,2,3,4,5,6] -->
{% for item in array limit:2 %}
{{- item -}}
{% endfor%}
{% for item2 in array offset:continue %}
{{- item2 -}}
{% endfor%}
```
输出
```text
12
123456
```
### range
+5
View File
@@ -47,7 +47,11 @@ export default {
return
}
const continueKey = 'continue-' + this.variable + '-' + this.collection.getText()
ctx.push({ continue: ctx.getRegister(continueKey) })
const hash = yield this.hash.render(ctx)
ctx.pop()
const modifiers = this.liquid.options.orderedFilterParameters
? Object.keys(hash).filter(x => MODIFIERS.includes(x))
: MODIFIERS.filter(x => hash[x] !== undefined)
@@ -58,6 +62,7 @@ export default {
return reversed(collection)
}, collection)
ctx.setRegister(continueKey, (hash['offset'] || 0) + collection.length)
const scope = { forloop: new ForloopDrop(collection.length, this.collection.getText(), this.variable) }
ctx.push(scope)
for (const item of collection) {
+21
View File
@@ -220,6 +220,27 @@ describe('tags/for', function () {
const html = await liquid.parseAndRender(src, scope)
return expect(html).to.equal('1 0 ')
})
it('should continue from limit-ed loop', async function () {
const src = '{%for i in arr limit:2%}{{i}}{%endfor%}-{%for i in arr offset:continue%}{{i}}{%endfor%}'
const html = await liquid.parseAndRender(src, { arr: [1, 2, 3, 4, 5] })
return expect(html).to.equal('12-345')
})
it('should continue nothing for fully iterated loop', async function () {
const src = '{%for i in arr%}{{i}}{%endfor%}-{%for i in arr offset:continue%}{{i}}{%endfor%}'
const html = await liquid.parseAndRender(src, { arr: [1, 2, 3, 4, 5] })
return expect(html).to.equal('12345-')
})
it('should treat different variable names as different forloop', async function () {
const src = '{%for i in (1..5)%}{{i}}{%endfor%}-{%for j in (1..5) offset:continue%}{{j}}{%endfor%}'
const html = await liquid.parseAndRender(src, {})
return expect(html).to.equal('12345-12345')
})
it('should treat different collection names as different forloop', async function () {
const src = '{%for i in arr1%}{{i}}{%endfor%}-{%for i in arr2 offset:continue%}{{i}}{%endfor%}'
const arr = [1, 2, 3, 4, 5]
const html = await liquid.parseAndRender(src, { arr1: arr, arr2: arr })
return expect(html).to.equal('12345-12345')
})
})
describe('reversed', function () {