Merge pull request #214 from yonaskolb/include_context

Context param for Include block
This commit is contained in:
Yonas Kolb
2018-05-10 18:01:02 +10:00
committed by GitHub
4 changed files with 28 additions and 6 deletions

View File

@@ -2,6 +2,12 @@
## Master ## Master
### Enhancements
- 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 ### Bug Fixes
- Fixed using quote as a filter parameter - Fixed using quote as a filter parameter

View File

@@ -3,19 +3,21 @@ import PathKit
class IncludeNode : NodeType { class IncludeNode : NodeType {
let templateName: Variable let templateName: Variable
let includeContext: String?
class func parse(_ parser: TokenParser, token: Token) throws -> NodeType { class func parse(_ parser: TokenParser, token: Token) throws -> NodeType {
let bits = token.components() let bits = token.components()
guard bits.count == 2 else { guard bits.count == 2 || bits.count == 3 else {
throw TemplateSyntaxError("'include' tag takes one argument, the template file to be included") 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])) return IncludeNode(templateName: Variable(bits[1]), includeContext: bits.count == 3 ? bits[2] : nil)
} }
init(templateName: Variable) { init(templateName: Variable, includeContext: String? = nil) {
self.templateName = templateName self.templateName = templateName
self.includeContext = includeContext
} }
func render(_ context: Context) throws -> String { func render(_ context: Context) throws -> String {
@@ -25,7 +27,8 @@ class IncludeNode : NodeType {
let template = try context.environment.loadTemplate(name: templateName) 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) return try template.render(context)
} }
} }

View File

@@ -14,7 +14,7 @@ func testInclude() {
let tokens: [Token] = [ .block(value: "include") ] let tokens: [Token] = [ .block(value: "include") ]
let parser = TokenParser(tokens: tokens, environment: Environment()) 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. 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) try expect(try parser.parse()).toThrow(error)
} }
@@ -56,6 +56,13 @@ func testInclude() {
let value = try node.render(context) let value = try node.render(context)
try expect(value) == "Hello World!" try expect(value) == "Hello World!"
} }
$0.it("successfully passes context") {
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!"
}
} }
} }
} }

View File

@@ -260,6 +260,12 @@ You can include another template using the `include` tag.
{% include "comment.html" %} {% 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 `include` tag requires you to provide a loader which will be used to lookup
the template. the template.