From 93c07e22b11400b749a2a420a4ab13bea72496c6 Mon Sep 17 00:00:00 2001 From: Ilya Puchka Date: Wed, 29 Nov 2017 23:03:16 +0100 Subject: [PATCH 1/2] fixed block inheritance with several levels --- CHANGELOG.md | 4 +++ Sources/Inheritence.swift | 35 ++++++++++++++++---- Tests/StencilTests/InheritenceSpec.swift | 6 ++-- Tests/StencilTests/fixtures/child-child.html | 2 +- Tests/StencilTests/fixtures/child-super.html | 2 +- Tests/StencilTests/fixtures/child.html | 3 +- 6 files changed, 39 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d38422c4..271da0f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Stencil Changelog +## Master + +- Fixed rendering `{{ block.super }}` with several levels of inheritance + ## 0.10.1 ### Enhancements diff --git a/Sources/Inheritence.swift b/Sources/Inheritence.swift index 9919c163..c656872b 100644 --- a/Sources/Inheritence.swift +++ b/Sources/Inheritence.swift @@ -1,14 +1,33 @@ 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.mapValues({ [$0] }) } + 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 +89,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 +126,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) } } diff --git a/Tests/StencilTests/InheritenceSpec.swift b/Tests/StencilTests/InheritenceSpec.swift index 6b741ae2..a58107a3 100644 --- a/Tests/StencilTests/InheritenceSpec.swift +++ b/Tests/StencilTests/InheritenceSpec.swift @@ -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" } } } diff --git a/Tests/StencilTests/fixtures/child-child.html b/Tests/StencilTests/fixtures/child-child.html index 5bb924e4..15245058 100644 --- a/Tests/StencilTests/fixtures/child-child.html +++ b/Tests/StencilTests/fixtures/child-child.html @@ -1,2 +1,2 @@ {% extends "child.html" %} -{% block header %}Child Child Header{% endblock %} +{% block header %}{{ block.super }} Child_Child_Header{% endblock %} diff --git a/Tests/StencilTests/fixtures/child-super.html b/Tests/StencilTests/fixtures/child-super.html index c8964ee6..2f6c38c9 100644 --- a/Tests/StencilTests/fixtures/child-super.html +++ b/Tests/StencilTests/fixtures/child-super.html @@ -1,3 +1,3 @@ {% extends "base.html" %} -{% block body %}Child {{ block.super }}{% endblock %} +{% block body %}Child_{{ block.super }}{% endblock %} diff --git a/Tests/StencilTests/fixtures/child.html b/Tests/StencilTests/fixtures/child.html index 30984785..0336878d 100644 --- a/Tests/StencilTests/fixtures/child.html +++ b/Tests/StencilTests/fixtures/child.html @@ -1,2 +1,3 @@ {% extends "base.html" %} -{% block body %}Child{% endblock %} \ No newline at end of file +{% block header %}Super_{{ block.super }} Child_Header{% endblock %} +{% block body %}Child_Body{% endblock %} From 1e6846867e4fb7b510f274d1f6f8a8e1ba827f24 Mon Sep 17 00:00:00 2001 From: Ilya Puchka Date: Wed, 29 Nov 2017 23:18:48 +0100 Subject: [PATCH 2/2] fixed compiling in swift 3 --- Sources/Inheritence.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Sources/Inheritence.swift b/Sources/Inheritence.swift index c656872b..b9bf87ac 100644 --- a/Sources/Inheritence.swift +++ b/Sources/Inheritence.swift @@ -4,7 +4,10 @@ class BlockContext { var blocks: [String: [BlockNode]] init(blocks: [String: BlockNode]) { - self.blocks = blocks.mapValues({ [$0] }) + self.blocks = [:] + blocks.forEach { (key, value) in + self.blocks[key] = [value] + } } func push(_ block: BlockNode, forKey blockName: String) {