Template inheritance (#9)

* Move all context variables into HBMustacheContext

* Add support for reading inherited sections

* Render inherited tokens

* Test inheritance spec, fix two minor issues

* fix warning

* swift format
This commit is contained in:
Adam Fowler
2021-03-22 12:02:22 +00:00
committed by GitHub
parent af345e9138
commit 35d52603e2
9 changed files with 232 additions and 59 deletions

View File

@@ -16,6 +16,12 @@ extension HBMustacheTemplate {
case expectedSectionEnd
/// set delimiter tag badly formatted
case invalidSetDelimiter
/// cannot apply transform to inherited section
case transformAppliedToInheritanceSection
/// illegal token inside inherit section of partial
case illegalTokenInsideInheritSection
/// text found inside inherit section of partial
case textInsideInheritSection
}
struct ParserState {
@@ -121,6 +127,21 @@ extension HBMustacheTemplate {
let sectionTokens = try parse(&parser, state: state.withSectionName(name, method: method))
tokens.append(.invertedSection(name: name, method: method, template: HBMustacheTemplate(sectionTokens)))
case "$":
// inherited section
parser.unsafeAdvance()
let (name, method) = try parseName(&parser, state: state)
// ERROR: can't have methods applied to inherited sections
guard method == nil else { throw Error.transformAppliedToInheritanceSection }
if self.isStandalone(&parser, state: state) {
setNewLine = true
} else if whiteSpaceBefore.count > 0 {
tokens.append(.text(String(whiteSpaceBefore)))
whiteSpaceBefore = ""
}
let sectionTokens = try parse(&parser, state: state.withSectionName(name, method: method))
tokens.append(.inheritedSection(name: name, template: HBMustacheTemplate(sectionTokens)))
case "/":
// end of section
parser.unsafeAdvance()
@@ -174,12 +195,40 @@ extension HBMustacheTemplate {
}
if self.isStandalone(&parser, state: state) {
setNewLine = true
tokens.append(.partial(name, indentation: String(whiteSpaceBefore)))
tokens.append(.partial(name, indentation: String(whiteSpaceBefore), inherits: nil))
} else {
tokens.append(.partial(name, indentation: nil))
tokens.append(.partial(name, indentation: nil, inherits: nil))
}
whiteSpaceBefore = ""
case "<":
// partial with inheritance
parser.unsafeAdvance()
let (name, method) = try parseName(&parser, state: state)
// ERROR: can't have methods applied to inherited sections
guard method == nil else { throw Error.transformAppliedToInheritanceSection }
var indent: String?
if self.isStandalone(&parser, state: state) {
setNewLine = true
} else if whiteSpaceBefore.count > 0 {
indent = String(whiteSpaceBefore)
tokens.append(.text(indent!))
whiteSpaceBefore = ""
}
let sectionTokens = try parse(&parser, state: state.withSectionName(name, method: method))
var inherit: [String: HBMustacheTemplate] = [:]
for token in sectionTokens {
switch token {
case .inheritedSection(let name, let template):
inherit[name] = template
case .text:
break
default:
throw Error.illegalTokenInsideInheritSection
}
}
tokens.append(.partial(name, indentation: indent, inherits: inherit))
case "=":
// set delimiter
parser.unsafeAdvance()