Skip to content

Commit

Permalink
Merge pull request #214 from yonaskolb/include_context
Browse files Browse the repository at this point in the history
Context param for Include block
  • Loading branch information
yonaskolb authored May 10, 2018
2 parents fc6c020 + 2627d3e commit d935f65
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 6 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

## 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

- Fixed using quote as a filter parameter
Expand Down
13 changes: 8 additions & 5 deletions Sources/Include.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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 == 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]))
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.includeContext = includeContext
}

func render(_ context: Context) throws -> String {
Expand All @@ -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)
}
}
Expand Down
9 changes: 8 additions & 1 deletion Tests/StencilTests/IncludeSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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. 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)
}

Expand Down Expand Up @@ -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\" child %}")
let context = Context(dictionary: ["child": ["target": "World"]], environment: environment)
let value = try template.render(context)
try expect(value) == "Hello World!"
}
}
}
}
6 changes: 6 additions & 0 deletions docs/builtins.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down

0 comments on commit d935f65

Please sign in to comment.