fix(extends): Support multiple extends

Fixes #60
This commit is contained in:
Kyle Fuller
2016-11-27 04:22:37 +00:00
parent a014fecd23
commit 393dc88a10
4 changed files with 30 additions and 8 deletions

View File

@@ -1,9 +1,9 @@
class BlockContext {
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
}
@@ -42,10 +42,9 @@ class ExtendsNode : NodeType {
throw TemplateSyntaxError("'extends' cannot appear more than once in the same template")
}
let blockNodes = parsedNodes.filter { node in node is BlockNode }
let blockNodes = parsedNodes.flatMap { $0 as? BlockNode }
let nodes = blockNodes.reduce([String:BlockNode]()) { (accumulator, node:NodeType) -> [String:BlockNode] in
let node = (node as! BlockNode)
let nodes = blockNodes.reduce([String: BlockNode]()) { (accumulator, node) -> [String: BlockNode] in
var dict = accumulator
dict[node.name] = node
return dict
@@ -69,11 +68,23 @@ class ExtendsNode : NodeType {
}
guard let template = loader.loadTemplate(templateName) else {
let paths:String = loader.paths.map { $0.description }.joined(separator: ", ")
let paths: String = loader.paths.map { $0.description }.joined(separator: ", ")
throw TemplateSyntaxError("'\(templateName)' template not found in \(paths)")
}
let blockContext = BlockContext(blocks: blocks)
let blockContext: BlockContext
if let context = context[BlockContext.contextKey] as? BlockContext {
blockContext = context
for (key, value) in blocks {
if !blockContext.blocks.keys.contains(key) {
blockContext.blocks[key] = value
}
}
} else {
blockContext = BlockContext(blocks: blocks)
}
return try context.push(dictionary: [BlockContext.contextKey: blockContext]) {
return try template.render(context)
}
@@ -89,7 +100,7 @@ class BlockNode : NodeType {
let bits = token.components()
guard bits.count == 2 else {
throw TemplateSyntaxError("'block' tag takes one argument, the template file to be included")
throw TemplateSyntaxError("'block' tag takes one argument, the block name")
}
let blockName = bits[1]