From 67eca80d618c15693541e272d9be589878d9bd95 Mon Sep 17 00:00:00 2001 From: Kyle Fuller Date: Sun, 26 Oct 2014 18:16:27 +0000 Subject: [PATCH] Provide simple API for tags Closes #6 --- README.md | 20 ++++++++++++++++++++ Stencil/Node.swift | 12 ++++++++++++ Stencil/Parser.swift | 6 ++++++ StencilTests/StencilTests.swift | 12 ++++++++++++ 4 files changed, 50 insertions(+) diff --git a/README.md b/README.md index cf88dde..ca08ba6 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,26 @@ A for loop allows you to iterate over an array found by variable lookup. {% endif %} ``` +#### Building custom tags + +You can build a custom template tag. There are a couple of APIs to allow +you to write your own custom tags. The following is the simplest form: + +```swift +template.parser.registerSimpleTag("custom") { context in + return .Success("Hello World") +} +``` + +When your tag is used via `{% custom %}` it will execute the registered block +of code allowing you to modify or retrieve a value from the context. Then +return either a string rendered in your template, or an error. + +If you want to accept arguments or to capture different tokens between two sets +of template tags. You will need to the `registerTag` API which accepts a +closure to handle the parsing. You can find examples of the `now`, `if` and +`for` tags found inside `Node.swift`. + ### Comments To comment out part of your template you can use the following syntax: diff --git a/Stencil/Node.swift b/Stencil/Node.swift index 9f34ec2..7661ada 100644 --- a/Stencil/Node.swift +++ b/Stencil/Node.swift @@ -52,6 +52,18 @@ public func renderNodes(nodes:[Node], context:Context) -> Result { return .Success(result) } +public class SimpleNode : Node { + let handler:(Context) -> (Result) + + public init(handler:((Context) -> (Result))) { + self.handler = handler + } + + public func render(context:Context) -> Result { + return handler(context) + } +} + public class TextNode : Node { public let text:String diff --git a/Stencil/Parser.swift b/Stencil/Parser.swift index c33e6c9..0f35bea 100644 --- a/Stencil/Parser.swift +++ b/Stencil/Parser.swift @@ -41,6 +41,12 @@ public class TokenParser { tags[name] = parser } + public func registerSimpleTag(name:String, handler:((Context) -> (Stencil.Result))) { + registerTag(name, parser: { (parser, token) -> TokenParser.Result in + return .Success(node:SimpleNode(handler: handler)) + }) + } + public func parse() -> Results { return parse(nil) } diff --git a/StencilTests/StencilTests.swift b/StencilTests/StencilTests.swift index 0eb4b57..d913773 100644 --- a/StencilTests/StencilTests.swift +++ b/StencilTests/StencilTests.swift @@ -64,4 +64,16 @@ class StencilTests: XCTestCase { let result = template.render() XCTAssertEqual(result, Result.Success("Hello World")) } + + func testSimpleCustomTag() { + let templateString = "{% custom %}" + let template = Template(templateString:templateString) + + template.parser.registerSimpleTag("custom") { context in + return .Success("Hello World") + } + + let result = template.render() + XCTAssertEqual(result, Result.Success("Hello World")) + } }