Merge pull request #154 from kylef/fix-block-inheritance
Fixed block inheritance with several levels
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
# Stencil Changelog
|
||||
|
||||
## Master
|
||||
|
||||
- Fixed rendering `{{ block.super }}` with several levels of inheritance
|
||||
|
||||
## 0.10.1
|
||||
|
||||
### Enhancements
|
||||
|
||||
@@ -1,14 +1,36 @@
|
||||
class BlockContext {
|
||||
class var contextKey: String { return "block_context" }
|
||||
|
||||
var blocks: [String: BlockNode]
|
||||
var 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? {
|
||||
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
|
||||
|
||||
for (key, value) in blocks {
|
||||
if !blockContext.blocks.keys.contains(key) {
|
||||
blockContext.blocks[key] = value
|
||||
}
|
||||
blockContext.push(value, forKey: key)
|
||||
}
|
||||
} else {
|
||||
blockContext = BlockContext(blocks: blocks)
|
||||
@@ -109,7 +129,11 @@ class BlockNode : NodeType {
|
||||
|
||||
func render(_ context: Context) throws -> String {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,17 +11,17 @@ func testInheritence() {
|
||||
|
||||
$0.it("can inherit from another template") {
|
||||
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") {
|
||||
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") {
|
||||
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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
{% extends "child.html" %}
|
||||
{% block header %}Child Child Header{% endblock %}
|
||||
{% block header %}{{ block.super }} Child_Child_Header{% endblock %}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
{% extends "base.html" %}
|
||||
{% block body %}Child {{ block.super }}{% endblock %}
|
||||
{% block body %}Child_{{ block.super }}{% endblock %}
|
||||
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
{% extends "base.html" %}
|
||||
{% block body %}Child{% endblock %}
|
||||
{% block header %}Super_{{ block.super }} Child_Header{% endblock %}
|
||||
{% block body %}Child_Body{% endblock %}
|
||||
|
||||
Reference in New Issue
Block a user