Merge pull request #154 from kylef/fix-block-inheritance

Fixed block inheritance with several levels
This commit is contained in:
Ilya Puchka
2017-11-30 10:43:51 +00:00
committed by GitHub
6 changed files with 42 additions and 13 deletions

View File

@@ -1,5 +1,9 @@
# Stencil Changelog # Stencil Changelog
## Master
- Fixed rendering `{{ block.super }}` with several levels of inheritance
## 0.10.1 ## 0.10.1
### Enhancements ### Enhancements

View File

@@ -1,14 +1,36 @@
class BlockContext { class BlockContext {
class var contextKey: String { return "block_context" } class var contextKey: String { return "block_context" }
var blocks: [String: BlockNode] var blocks: [String: [BlockNode]]
init(blocks: [String: BlockNode]) { init(blocks: [String: BlockNode]) {
self.blocks = blocks self.blocks = [:]
blocks.forEach { (key, value) in
self.blocks[key] = [value]
}
} }
func push(_ block: BlockNode, forKey blockName: String) {
if var blocks = blocks[blockName] {
blocks.append(block)
self.blocks[blockName] = blocks
} else {
self.blocks[blockName] = [block]
}
}
func pop(_ blockName: String) -> BlockNode? { func pop(_ blockName: String) -> BlockNode? {
return blocks.removeValue(forKey: blockName) if var blocks = blocks[blockName] {
let block = blocks.removeFirst()
if blocks.isEmpty {
self.blocks.removeValue(forKey: blockName)
} else {
self.blocks[blockName] = blocks
}
return block
} else {
return nil
}
} }
} }
@@ -70,9 +92,7 @@ class ExtendsNode : NodeType {
blockContext = context blockContext = context
for (key, value) in blocks { for (key, value) in blocks {
if !blockContext.blocks.keys.contains(key) { blockContext.push(value, forKey: key)
blockContext.blocks[key] = value
}
} }
} else { } else {
blockContext = BlockContext(blocks: blocks) blockContext = BlockContext(blocks: blocks)
@@ -109,7 +129,11 @@ class BlockNode : NodeType {
func render(_ context: Context) throws -> String { func render(_ context: Context) throws -> String {
if let blockContext = context[BlockContext.contextKey] as? BlockContext, let node = blockContext.pop(name) { if let blockContext = context[BlockContext.contextKey] as? BlockContext, let node = blockContext.pop(name) {
return try context.push(dictionary: ["block": ["super": self]]) { let newContext: [String: Any] = [
BlockContext.contextKey: blockContext,
"block": ["super": try self.render(context)]
]
return try context.push(dictionary: newContext) {
return try node.render(context) return try node.render(context)
} }
} }

View File

@@ -11,17 +11,17 @@ func testInheritence() {
$0.it("can inherit from another template") { $0.it("can inherit from another template") {
let template = try environment.loadTemplate(name: "child.html") let template = try environment.loadTemplate(name: "child.html")
try expect(try template.render()) == "Header\nChild" try expect(try template.render()) == "Super_Header Child_Header\nChild_Body"
} }
$0.it("can inherit from another template inheriting from another template") { $0.it("can inherit from another template inheriting from another template") {
let template = try environment.loadTemplate(name: "child-child.html") let template = try environment.loadTemplate(name: "child-child.html")
try expect(try template.render()) == "Child Child Header\nChild" try expect(try template.render()) == "Super_Header Child_Header Child_Child_Header\nChild_Body"
} }
$0.it("can inherit from a template that calls a super block") { $0.it("can inherit from a template that calls a super block") {
let template = try environment.loadTemplate(name: "child-super.html") let template = try environment.loadTemplate(name: "child-super.html")
try expect(try template.render()) == "Header\nChild Body" try expect(try template.render()) == "Header\nChild_Body"
} }
} }
} }

View File

@@ -1,2 +1,2 @@
{% extends "child.html" %} {% extends "child.html" %}
{% block header %}Child Child Header{% endblock %} {% block header %}{{ block.super }} Child_Child_Header{% endblock %}

View File

@@ -1,3 +1,3 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block body %}Child {{ block.super }}{% endblock %} {% block body %}Child_{{ block.super }}{% endblock %}

View File

@@ -1,2 +1,3 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block body %}Child{% endblock %} {% block header %}Super_{{ block.super }} Child_Header{% endblock %}
{% block body %}Child_Body{% endblock %}