Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Context param for Include block #214

Merged
merged 7 commits into from
May 10, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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