diff --git a/Fluid.Tests/ForStatementTests.cs b/Fluid.Tests/ForStatementTests.cs index 2483cf41..04b346fb 100644 --- a/Fluid.Tests/ForStatementTests.cs +++ b/Fluid.Tests/ForStatementTests.cs @@ -176,6 +176,16 @@ public async Task ForShouldProvideHelperVariables() [Fact] public async Task ForShouldBeNestable() { + /* + * {% for i in items %} + * {{ forloop.index }} + * {% for j in items %} + * {{ forloop.index }} + * {% endfor %} + * {% endfor %} + * + */ + var nested = new ForStatement( new List { CreateMemberStatement("forloop.index") @@ -207,6 +217,50 @@ public async Task ForShouldBeNestable() Assert.Equal("112321233123", sw.ToString()); } + [Fact] + public async Task NestedForShouldProvideParentLoop() + { + /* + * {% for i in items %} + * {{ forloop.index }} + * {% for j in items %} + * {{ parentloop.index }} + * {% endfor %} + * {% endfor %} + * + */ + + var nested = new ForStatement( + new List { + CreateMemberStatement("parentloop.index") + }, + "j", + new MemberExpression( + new IdentifierSegment("items") + ), + null, null, false + ); + + var outer = new ForStatement( + new List { + CreateMemberStatement("forloop.index"), + nested + }, + "i", + new MemberExpression( + new IdentifierSegment("items") + ), + null, null, false + ); + + var sw = new StringWriter(); + var context = new TemplateContext(); + context.SetValue("items", new[] { 1, 2, 3 }); + await outer.WriteToAsync(sw, HtmlEncoder.Default, context); + + Assert.Equal("111122223333", sw.ToString()); + } + [Fact] public async Task ForEvaluatesOptions() { diff --git a/Fluid/Ast/ForStatement.cs b/Fluid/Ast/ForStatement.cs index cdd54eb5..c9e1affb 100644 --- a/Fluid/Ast/ForStatement.cs +++ b/Fluid/Ast/ForStatement.cs @@ -103,6 +103,8 @@ public override async ValueTask WriteToAsync(TextWriter writer, Text source.Reverse(startIndex, count); } + var parentLoop = context.LocalScope.GetValue("forloop"); + context.EnterForLoopScope(); try @@ -113,6 +115,11 @@ public override async ValueTask WriteToAsync(TextWriter writer, Text context.LocalScope._properties["forloop"] = forloop; + if (!parentLoop.IsNil()) + { + context.LocalScope._properties["parentloop"] = parentLoop; + } + for (var i = startIndex; i < length; i++) { context.IncrementSteps();