Skip to content

Commit f41765d

Browse files
committed
change filter to filterEach and added filter to apply dynamic filter
1 parent 94acc6e commit f41765d

File tree

4 files changed

+38
-6
lines changed

4 files changed

+38
-6
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
their stored properties.
1010
- Allow default string filters to be applied to arrays
1111
- Similar filters are suggested when unknown filter is used
12-
- Added `indent`, `split`, `map`, `compact` and `filter` filters
12+
- Added `indent`, `split`, `map`, `compact`, `filterEach` and `filter` filters
1313

1414
### Bug Fixes
1515

Sources/Extension.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ class DefaultExtension: Extension {
6565
registerFilter("indent", filter: indentFilter)
6666
registerFilter("map", filter: mapFilter)
6767
registerFilter("compact", filter: compactFilter)
68+
registerFilter("filterEach", filter: filterEachFilter)
6869
registerFilter("filter", filter: filterFilter)
6970
}
7071
}

Sources/Filters.swift

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,9 @@ func compactFilter(value: Any?, arguments: [Any?], context: Context) throws -> A
156156
})
157157
}
158158

159-
func filterFilter(value: Any?, arguments: [Any?], context: Context) throws -> Any? {
159+
func filterEachFilter(value: Any?, arguments: [Any?], context: Context) throws -> Any? {
160160
guard arguments.count == 1 else {
161-
throw TemplateSyntaxError("'filter' filter takes one argument")
161+
throw TemplateSyntaxError("'filterEach' filter takes one argument")
162162
}
163163

164164
let attribute = stringify(arguments[0])
@@ -176,3 +176,18 @@ func filterFilter(value: Any?, arguments: [Any?], context: Context) throws -> An
176176
return value
177177
}
178178

179+
func filterFilter(value: Any?, arguments: [Any?], context: Context) throws -> Any? {
180+
guard let value = value else { return nil }
181+
guard arguments.count == 1 else {
182+
throw TemplateSyntaxError("'filter' filter takes one argument")
183+
}
184+
185+
let attribute = stringify(arguments[0])
186+
let parser = TokenParser(tokens: [], environment: context.environment)
187+
188+
let expr = try parser.compileFilter("$0|\(attribute)")
189+
return try context.push(dictionary: ["$0": value]) {
190+
try expr.resolve(context)
191+
}
192+
}
193+

Tests/StencilTests/FilterSpec.swift

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -316,24 +316,40 @@ func testFilter() {
316316

317317
}
318318

319-
describe("filter filter") {
319+
describe("filterEach filter") {
320320

321321
$0.it("can filter using filter") {
322322
let env = environmentWithFilter("isPositive") { (value) -> Any? in
323323
if let number = toNumber(value: value as Any) { return number > 0 }
324324
else { return nil }
325325
}
326326

327-
let template = Template(templateString: "{{ array|filter:'$0|isPositive' }}")
327+
let template = Template(templateString: "{{ array|filterEach:'$0|isPositive' }}")
328328
let result = try template.render(Context(dictionary: ["array": [1, -1, 2, -2, 3, -3]], environment: env))
329329
try expect(result) == "[1, 2, 3]"
330330
}
331331

332332
$0.it("can filter using boolean expression") {
333-
let template = Template(templateString: "{{ array|filter:'$0 > 0' }}")
333+
let template = Template(templateString: "{{ array|filterEach:'$0 > 0' }}")
334334
let result = try template.render(Context(dictionary: ["array": [1, -1, 2, -2, 3, -3]]))
335335
try expect(result) == "[1, 2, 3]"
336336
}
337337

338338
}
339+
340+
describe("filter filter") {
341+
342+
$0.it("can apply dynamic filter") {
343+
let template = Template(templateString: "{{ name|filter:somefilter }}")
344+
let result = try template.render(Context(dictionary: ["name": "Jhon", "somefilter": "uppercase"]))
345+
try expect(result) == "JHON"
346+
}
347+
348+
$0.it("can apply dynamic filter on array") {
349+
let template = Template(templateString: "{{ values|filter:joinfilter }}")
350+
let result = try template.render(Context(dictionary: ["values": [1, 2, 3], "joinfilter": "join:\", \""]))
351+
try expect(result) == "1, 2, 3"
352+
}
353+
354+
}
339355
}

0 commit comments

Comments
 (0)