feat: Allow subclassing templates (#79)
This commit is contained in:
@@ -56,6 +56,9 @@
|
|||||||
- You can now use `{{ block.super }}` to render a super block from another `{%
|
- You can now use `{{ block.super }}` to render a super block from another `{%
|
||||||
block %}`.
|
block %}`.
|
||||||
|
|
||||||
|
- `Environment` allows you to provide a custom `Template` subclass, allowing
|
||||||
|
new template to use a specific subclass.
|
||||||
|
|
||||||
### Deprecations
|
### Deprecations
|
||||||
|
|
||||||
- `Template` initialisers have been deprecated in favour of using a template
|
- `Template` initialisers have been deprecated in favour of using a template
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
public struct Environment {
|
public struct Environment {
|
||||||
|
public let templateClass: Template.Type
|
||||||
public let extensions: [Extension]
|
public let extensions: [Extension]
|
||||||
|
|
||||||
public var loader: Loader?
|
public var loader: Loader?
|
||||||
|
|
||||||
public init(loader: Loader? = nil, extensions: [Extension]? = nil) {
|
public init(loader: Loader? = nil, extensions: [Extension]? = nil, templateClass: Template.Type = Template.self) {
|
||||||
|
self.templateClass = templateClass
|
||||||
self.loader = loader
|
self.loader = loader
|
||||||
self.extensions = [DefaultExtension()] + (extensions ?? [])
|
self.extensions = [DefaultExtension()] + (extensions ?? [])
|
||||||
}
|
}
|
||||||
@@ -30,7 +32,7 @@ public struct Environment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public func renderTemplate(string: String, context: [String: Any]? = nil) throws -> String {
|
public func renderTemplate(string: String, context: [String: Any]? = nil) throws -> String {
|
||||||
let template = Template(templateString: string, environment: self)
|
let template = templateClass.init(templateString: string, environment: self)
|
||||||
return try template.render(context)
|
return try template.render(context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,8 @@ public class FileSystemLoader: Loader, CustomStringConvertible {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
return try Template(path: templatePath, environment: environment, name: name)
|
let content: String = try templatePath.read()
|
||||||
|
return try environment.templateClass.init(templateString: content, environment: environment, name: name)
|
||||||
}
|
}
|
||||||
|
|
||||||
throw TemplateDoesNotExist(templateNames: [name], loader: self)
|
throw TemplateDoesNotExist(templateNames: [name], loader: self)
|
||||||
@@ -63,7 +64,8 @@ public class FileSystemLoader: Loader, CustomStringConvertible {
|
|||||||
let templatePath = try path.safeJoin(path: Path(templateName))
|
let templatePath = try path.safeJoin(path: Path(templateName))
|
||||||
|
|
||||||
if templatePath.exists {
|
if templatePath.exists {
|
||||||
return try Template(path: templatePath, environment: environment, name: templateName)
|
let content: String = try templatePath.read()
|
||||||
|
return try environment.templateClass.init(templateString: content, environment: environment, name: templateName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ let NSFileNoSuchFileError = 4
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// A class representing a template
|
/// A class representing a template
|
||||||
public class Template: ExpressibleByStringLiteral {
|
open class Template: ExpressibleByStringLiteral {
|
||||||
let environment: Environment
|
let environment: Environment
|
||||||
let tokens: [Token]
|
let tokens: [Token]
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@ public class Template: ExpressibleByStringLiteral {
|
|||||||
public let name: String?
|
public let name: String?
|
||||||
|
|
||||||
/// Create a template with a template string
|
/// Create a template with a template string
|
||||||
public init(templateString: String, environment: Environment? = nil, name: String? = nil) {
|
public required init(templateString: String, environment: Environment? = nil, name: String? = nil) {
|
||||||
self.environment = environment ?? Environment()
|
self.environment = environment ?? Environment()
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|
||||||
@@ -71,7 +71,7 @@ public class Template: ExpressibleByStringLiteral {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Render the given template
|
/// Render the given template
|
||||||
public func render(_ dictionary: [String: Any]? = nil) throws -> String {
|
open func render(_ dictionary: [String: Any]? = nil) throws -> String {
|
||||||
return try render(Context(dictionary: dictionary, environment: environment))
|
return try render(Context(dictionary: dictionary, environment: environment))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,11 +25,17 @@ func testEnvironment() {
|
|||||||
let result = try environment.renderTemplate(name: "example.html")
|
let result = try environment.renderTemplate(name: "example.html")
|
||||||
try expect(result) == "Hello World!"
|
try expect(result) == "Hello World!"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$0.it("allows you to provide a custom template class") {
|
||||||
|
let environment = Environment(loader: ExampleLoader(), templateClass: CustomTemplate.self)
|
||||||
|
let result = try environment.renderTemplate(string: "Hello World")
|
||||||
|
|
||||||
|
try expect(result) == "here"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fileprivate class ExampleLoader: Loader {
|
fileprivate class ExampleLoader: Loader {
|
||||||
func loadTemplate(name: String, environment: Environment) throws -> Template {
|
func loadTemplate(name: String, environment: Environment) throws -> Template {
|
||||||
if name == "example.html" {
|
if name == "example.html" {
|
||||||
@@ -39,3 +45,10 @@ fileprivate class ExampleLoader: Loader {
|
|||||||
throw TemplateDoesNotExist(templateNames: [name], loader: self)
|
throw TemplateDoesNotExist(templateNames: [name], loader: self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class CustomTemplate: Template {
|
||||||
|
override func render(_ dictionary: [String: Any]? = nil) throws -> String {
|
||||||
|
return "here"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user