From 7679b48164331a54eb20e3a85fd2ac2b426a7390 Mon Sep 17 00:00:00 2001 From: Yonas Kolb Date: Mon, 30 Apr 2018 11:45:22 +1000 Subject: [PATCH 1/6] add contex to include --- Sources/Include.swift | 13 ++++++++----- Tests/StencilTests/IncludeSpec.swift | 9 ++++++++- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/Sources/Include.swift b/Sources/Include.swift index cd9cc5cf..3fc90512 100644 --- a/Sources/Include.swift +++ b/Sources/Include.swift @@ -3,19 +3,21 @@ import PathKit class IncludeNode : NodeType { let templateName: Variable + let includeContext: String? class func parse(_ parser: TokenParser, token: Token) throws -> NodeType { let bits = token.components() - guard bits.count == 2 else { - throw TemplateSyntaxError("'include' tag takes one argument, the template file to be included") + guard bits.count == 2 || (bits.count == 4 && bits[2] == "using") else { + throw TemplateSyntaxError("'include' tag requires one argument, the template file to be included. Another optional argument can be used to specify the context that will be passed to the included file, using the format \"using myContext\"") } - return IncludeNode(templateName: Variable(bits[1])) + return IncludeNode(templateName: Variable(bits[1]), includeContext: bits.count == 4 ? bits[3] : nil) } - init(templateName: Variable) { + init(templateName: Variable, includeContext: String? = nil) { self.templateName = templateName + self.includeContext = includeContext } func render(_ context: Context) throws -> String { @@ -25,7 +27,8 @@ class IncludeNode : NodeType { let template = try context.environment.loadTemplate(name: templateName) - return try context.push { + let subContext = includeContext.flatMap{ context[$0] as? [String: Any] } + return try context.push(dictionary: subContext) { return try template.render(context) } } diff --git a/Tests/StencilTests/IncludeSpec.swift b/Tests/StencilTests/IncludeSpec.swift index 02978965..cf785e28 100644 --- a/Tests/StencilTests/IncludeSpec.swift +++ b/Tests/StencilTests/IncludeSpec.swift @@ -14,7 +14,7 @@ func testInclude() { let tokens: [Token] = [ .block(value: "include") ] let parser = TokenParser(tokens: tokens, environment: Environment()) - let error = TemplateSyntaxError("'include' tag takes one argument, the template file to be included") + let error = TemplateSyntaxError("'include' tag requires one argument, the template file to be included. Another optional argument can be used to specify the context that will be passed to the included file, using the format \"using myContext\"") try expect(try parser.parse()).toThrow(error) } @@ -56,6 +56,13 @@ func testInclude() { let value = try node.render(context) try expect(value) == "Hello World!" } + + $0.it("successfully passes context") { + let template = Template(templateString: "{% include \"test.html\" using child %}") + let context = Context(dictionary: ["child": ["target": "World"]], environment: environment) + let value = try template.render(context) + try expect(value) == "Hello World!" + } } } } From 098af2a7b68ffa9ee7e40e0318a31d997d96409d Mon Sep 17 00:00:00 2001 From: Yonas Kolb Date: Mon, 30 Apr 2018 12:00:54 +1000 Subject: [PATCH 2/6] remove "using" param name --- Sources/Include.swift | 6 +++--- Tests/StencilTests/IncludeSpec.swift | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Sources/Include.swift b/Sources/Include.swift index 3fc90512..1bccb225 100644 --- a/Sources/Include.swift +++ b/Sources/Include.swift @@ -8,11 +8,11 @@ class IncludeNode : NodeType { class func parse(_ parser: TokenParser, token: Token) throws -> NodeType { let bits = token.components() - guard bits.count == 2 || (bits.count == 4 && bits[2] == "using") else { - throw TemplateSyntaxError("'include' tag requires one argument, the template file to be included. Another optional argument can be used to specify the context that will be passed to the included file, using the format \"using myContext\"") + guard bits.count == 2 || bits.count == 3 else { + throw TemplateSyntaxError("'include' tag requires one argument, the template file to be included. A second optional argument can be used to specify the context that will be passed to the included file") } - return IncludeNode(templateName: Variable(bits[1]), includeContext: bits.count == 4 ? bits[3] : nil) + return IncludeNode(templateName: Variable(bits[1]), includeContext: bits.count == 3 ? bits[2] : nil) } init(templateName: Variable, includeContext: String? = nil) { diff --git a/Tests/StencilTests/IncludeSpec.swift b/Tests/StencilTests/IncludeSpec.swift index cf785e28..1ad004fc 100644 --- a/Tests/StencilTests/IncludeSpec.swift +++ b/Tests/StencilTests/IncludeSpec.swift @@ -14,7 +14,7 @@ func testInclude() { let tokens: [Token] = [ .block(value: "include") ] let parser = TokenParser(tokens: tokens, environment: Environment()) - let error = TemplateSyntaxError("'include' tag requires one argument, the template file to be included. Another optional argument can be used to specify the context that will be passed to the included file, using the format \"using myContext\"") + let error = TemplateSyntaxError("'include' tag requires one argument, the template file to be included. A second optional argument can be used to specify the context that will be passed to the included file") try expect(try parser.parse()).toThrow(error) } @@ -58,7 +58,7 @@ func testInclude() { } $0.it("successfully passes context") { - let template = Template(templateString: "{% include \"test.html\" using child %}") + let template = Template(templateString: "{% include \"test.html\" child %}") let context = Context(dictionary: ["child": ["target": "World"]], environment: environment) let value = try template.render(context) try expect(value) == "Hello World!" From 1427e10698f5ac500f0b9c9263984621fd13ec6e Mon Sep 17 00:00:00 2001 From: Yonas Kolb Date: Mon, 7 May 2018 18:45:02 +1000 Subject: [PATCH 3/6] update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8bba3744..ba137376 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,10 @@ ## Master +### Enhancements + +- added an optional second parameter to the `include` tag for passing a sub context to the included file + ### Bug Fixes - Fixed using quote as a filter parameter From 47f2b33d80e41de8988ca700f62c6f1beffc126d Mon Sep 17 00:00:00 2001 From: Yonas Kolb Date: Mon, 7 May 2018 18:45:17 +1000 Subject: [PATCH 4/6] code formatting --- Sources/Include.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Include.swift b/Sources/Include.swift index 1bccb225..560bb74d 100644 --- a/Sources/Include.swift +++ b/Sources/Include.swift @@ -27,7 +27,7 @@ class IncludeNode : NodeType { let template = try context.environment.loadTemplate(name: templateName) - let subContext = includeContext.flatMap{ context[$0] as? [String: Any] } + let subContext = includeContext.flatMap { context[$0] as? [String: Any] } return try context.push(dictionary: subContext) { return try template.render(context) } From 1e77f1e85f5a1226f2d5e82104a6ef23713073ae Mon Sep 17 00:00:00 2001 From: Yonas Kolb Date: Mon, 7 May 2018 18:46:20 +1000 Subject: [PATCH 5/6] document new include param --- docs/builtins.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/builtins.rst b/docs/builtins.rst index 9d61ecaa..d4cc99a3 100644 --- a/docs/builtins.rst +++ b/docs/builtins.rst @@ -260,6 +260,12 @@ You can include another template using the `include` tag. {% include "comment.html" %} +By default the included file gets passed the current context. You can pass a sub context by using an optional 2nd parameter as a lookup in the current context. + +.. code-block:: html+django + + {% include "comment.html" comment %} + The `include` tag requires you to provide a loader which will be used to lookup the template. From 2627d3e0d12850cbb9a9d626a5594781ba24fb01 Mon Sep 17 00:00:00 2001 From: Yonas Kolb Date: Thu, 10 May 2018 17:50:59 +1000 Subject: [PATCH 6/6] update changelog formatting --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba137376..6c87fe72 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,9 @@ ### Enhancements -- added an optional second parameter to the `include` tag for passing a sub context to the included file +- Added an optional second parameter to the `include` tag for passing a sub context to the included file. + [Yonas Kolb](https://github.com/yonaskolb) + [#394](https://github.com/stencilproject/Stencil/pull/214) ### Bug Fixes