From 9fdbbc99e90c781bd14428d44876559641d7f923 Mon Sep 17 00:00:00 2001 From: Kyle Fuller Date: Sun, 27 Nov 2016 19:47:50 +0000 Subject: [PATCH] feat(filters): Add a join filter --- CHANGELOG.md | 6 ++++++ Sources/Filters.swift | 16 ++++++++++++++++ Sources/Namespace.swift | 1 + Tests/StencilTests/FilterSpec.swift | 9 +++++++++ docs/builtins.rst | 11 +++++++++++ 5 files changed, 43 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed1d734..4ba0080 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,12 @@ Hello {{ name|default:"World" }} ``` +- There is now a `join` filter. + + ```html+django + {{ value|join:", " }} + ``` + ### Bug Fixes - Variables (`{{ variable.5 }}`) that reference an array index at an unknown diff --git a/Sources/Filters.swift b/Sources/Filters.swift index 1574a58..0bac235 100644 --- a/Sources/Filters.swift +++ b/Sources/Filters.swift @@ -35,3 +35,19 @@ func lowercase(_ value: Any?) -> Any? { func defaultFilter(value: Any?, arguments: [Any?]) -> Any? { return value ?? arguments.first as Any } + +func joinFilter(value: Any?, arguments: [Any?]) throws -> Any? { + guard arguments.count == 1 else { + throw TemplateSyntaxError("'join' filter takes a single argument") + } + + guard let separator = arguments.first as? String else { + throw TemplateSyntaxError("'join' filter takes a separator as string") + } + + if let value = value as? [String] { + return value.joined(separator: separator) + } + + return nil +} diff --git a/Sources/Namespace.swift b/Sources/Namespace.swift index 2b1d41e..fd62d99 100644 --- a/Sources/Namespace.swift +++ b/Sources/Namespace.swift @@ -49,6 +49,7 @@ public class Namespace { registerFilter("capitalize", filter: capitalise) registerFilter("uppercase", filter: uppercase) registerFilter("lowercase", filter: lowercase) + registerFilter("join", filter: joinFilter) } /// Registers a new template tag diff --git a/Tests/StencilTests/FilterSpec.swift b/Tests/StencilTests/FilterSpec.swift index 824ba80..60d6c39 100644 --- a/Tests/StencilTests/FilterSpec.swift +++ b/Tests/StencilTests/FilterSpec.swift @@ -103,4 +103,13 @@ func testFilter() { try expect(result) == "Hello World" } } + + describe("join filter") { + let template = Template(templateString: "{{ value|join:\", \" }}") + + $0.it("transforms a string to be lowercase") { + let result = try template.render(Context(dictionary: ["value": ["One", "Two"]])) + try expect(result) == "One, Two" + } + } } diff --git a/docs/builtins.rst b/docs/builtins.rst index 6b3bcbe..dab8a41 100644 --- a/docs/builtins.rst +++ b/docs/builtins.rst @@ -130,3 +130,14 @@ value of the variable. For example: .. code-block:: html+django Hello {{ name|default:"World" }} + +``join`` +~~~~~~~~ + +Join an array with a string. + +.. code-block:: html+django + + {{ value|join:", " }} + +.. note:: The value MUST be an array of Strngs and the separator must be a string.