diff --git a/Sources/Node.swift b/Sources/Node.swift index 8345989..c63e241 100644 --- a/Sources/Node.swift +++ b/Sources/Node.swift @@ -158,8 +158,15 @@ public class ForNode : NodeType { let values = try variable.resolve(context) if let values = values as? [Any] where values.count > 0 { - return try values.map { item in - try context.push([loopVariable: item]) { + let count = values.count + return try values.enumerate().map { index, item in + let forContext = [ + "first": index == 0, + "last": index == (count - 1), + "counter": index + 1, + ] + + return try context.push([loopVariable: item, "forloop": forContext]) { try renderNodes(nodes, context) } }.joinWithSeparator("") diff --git a/Specs/Nodes/ForNodeSpec.swift b/Specs/Nodes/ForNodeSpec.swift index 6dca534..258fb1d 100644 --- a/Specs/Nodes/ForNodeSpec.swift +++ b/Specs/Nodes/ForNodeSpec.swift @@ -20,4 +20,22 @@ describe("ForNode") { let node = ForNode(variable: "emptyItems", loopVariable: "item", nodes: nodes, emptyNodes: emptyNodes) try expect(try node.render(context)) == "empty" } + + $0.it("renders the given nodes while providing if the item is first in the context") { + let nodes: [NodeType] = [VariableNode(variable: "item"), VariableNode(variable: "forloop.first")] + let node = ForNode(variable: "items", loopVariable: "item", nodes: nodes, emptyNodes: []) + try expect(try node.render(context)) == "112030" + } + + $0.it("renders the given nodes while providing if the item is last in the context") { + let nodes: [NodeType] = [VariableNode(variable: "item"), VariableNode(variable: "forloop.last")] + let node = ForNode(variable: "items", loopVariable: "item", nodes: nodes, emptyNodes: []) + try expect(try node.render(context)) == "102031" + } + + $0.it("renders the given nodes while providing item counter") { + let nodes: [NodeType] = [VariableNode(variable: "item"), VariableNode(variable: "forloop.counter")] + let node = ForNode(variable: "items", loopVariable: "item", nodes: nodes, emptyNodes: []) + try expect(try node.render(context)) == "112233" + } }