diff --git a/docs/source/tags/for.md b/docs/source/tags/for.md index f34e8a68e..9177d9431 100644 --- a/docs/source/tags/for.md +++ b/docs/source/tags/for.md @@ -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 - + {% 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 - + {% 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 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 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 diff --git a/docs/source/zh-cn/tags/for.md b/docs/source/zh-cn/tags/for.md index 84e9d40ee..474fdef94 100644 --- a/docs/source/zh-cn/tags/for.md +++ b/docs/source/zh-cn/tags/for.md @@ -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 {% for item in array limit:2 %} - {{ item }} + {{- item -}} {% endfor %} ``` 输出 ```text -1 2 +12 ``` ### offset @@ -152,15 +152,57 @@ index index0 rindex rindex0 输入 ```liquid - + {% 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 item in array limit:2 %} + {{- item -}} +{% endfor%} +{% for item in array offset:continue %} + {{- item -}} +{% endfor%} +``` + +输出 +```text +12 +3456 +``` + +对同样的变量名和集合名(这个例子中是 `"item-array"`),存在唯一的位置记录。也就是说用新的变量名就可以开启一个新的循环: + +输入 +```liquid + +{% for item in array limit:2 %} + {{- item -}} +{% endfor%} +{% for item2 in array offset:continue %} + {{- item2 -}} +{% endfor%} +``` + +输出 +```text +12 +123456 ``` ### range diff --git a/src/builtin/tags/for.ts b/src/builtin/tags/for.ts index 49aad563f..40c3181c4 100644 --- a/src/builtin/tags/for.ts +++ b/src/builtin/tags/for.ts @@ -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) { diff --git a/test/integration/builtin/tags/for.ts b/test/integration/builtin/tags/for.ts index 303206c84..2fcce2be1 100644 --- a/test/integration/builtin/tags/for.ts +++ b/test/integration/builtin/tags/for.ts @@ -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 () {