Skip to content
This repository was archived by the owner on Aug 4, 2022. It is now read-only.

Commit 954bc7a

Browse files
authored
Merge pull request #11 from g-Off/t-filter
Implemented t filter
2 parents 139ae54 + 70ebbcd commit 954bc7a

File tree

5 files changed

+74
-6
lines changed

5 files changed

+74
-6
lines changed

Sources/Liquid/Context.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,17 +47,19 @@ public final class Context {
4747
private var registers: [String: Any] = [:]
4848

4949
public let filters: [String: FilterFunc]
50+
public let translations: [String: String]?
5051
public let tags: [String: TagBuilder]
5152
public let environment: Environment
5253
public let encoder: Encoder
5354
public let fileSystem: FileSystem
5455

55-
init(fileSystem: FileSystem, values: [String: Value] = [:], environment: Environment = Environment(), tags: [String: TagBuilder], filters: [String: FilterFunc] = [:], encoder: Encoder) {
56+
init(fileSystem: FileSystem, values: [String: Value] = [:], environment: Environment = Environment(), tags: [String: TagBuilder], filters: [String: FilterFunc] = [:], translations: [String: String]? = nil, encoder: Encoder) {
5657
self.fileSystem = fileSystem
5758
self.scopes = [Scope(values: values)]
5859
self.environment = environment
5960
self.tags = tags
6061
self.filters = filters
62+
self.translations = translations
6163
self.encoder = encoder
6264
}
6365

Sources/Liquid/Filter+Standard.swift

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ enum Filters {
5454
template.registerFilter(name: "sort", filter: sortFilter)
5555
template.registerFilter(name: "sort_natural", filter: sortNaturalFilter)
5656
template.registerFilter(name: "date", filter: dateFilter)
57+
template.registerFilter(name: "t", filter: tFilter)
5758
}
5859

5960
static func appendFilter(value: Value, args: [Value], kwargs: [String: Value], context: FilterContext) throws -> Value {
@@ -512,6 +513,25 @@ enum Filters {
512513
}
513514
return Value(formatter.string(from: date))
514515
}
516+
517+
static func tFilter(value: Value, args: [Value], kwargs: [String: Value], context: FilterContext) throws -> Value {
518+
guard let translations = context.translations else {
519+
throw RuntimeError.reason("No translations dictionary available")
520+
}
521+
522+
guard let val = translations[value.toString()] else {
523+
throw RuntimeError.reason("Invalid translation key")
524+
}
525+
526+
if kwargs.isEmpty && args.isEmpty {
527+
return Value(val)
528+
}
529+
if !kwargs.isEmpty {
530+
return Value(val.replaceWithValues(kwargs))
531+
}
532+
533+
throw RuntimeError.unimplemented
534+
}
515535

516536
private static func convertValueToDate(_ value: Value, context: FilterContext) -> Date? {
517537
if value.isInteger {
@@ -530,3 +550,28 @@ enum Filters {
530550
return context.encoder.dateEncodingStrategry.date(from: string)
531551
}
532552
}
553+
554+
private extension String {
555+
func replaceWithValues(_ values: [String: Value]) -> String {
556+
let scanner = Scanner(string: self)
557+
scanner.charactersToBeSkipped = CharacterSet.newlines
558+
559+
var result: String = ""
560+
var temp: NSString?
561+
562+
while !scanner.isAtEnd {
563+
scanner.scanUpTo("%{", into: &temp)
564+
scanner.scanCharacters(from: CharacterSet.init(charactersIn: "%{"), into: nil)
565+
566+
result = "\(result)\(temp ?? "")"
567+
568+
scanner.scanUpTo("}", into: &temp)
569+
scanner.scanCharacters(from: CharacterSet.init(charactersIn: "}"), into: nil)
570+
571+
let resultValue = values[String(temp ?? "")]?.toString() ?? ""
572+
result = "\(result)\(resultValue)"
573+
}
574+
575+
return result
576+
}
577+
}

Sources/Liquid/FilterContext.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@ import Foundation
99

1010
public struct FilterContext {
1111
public let encoder: Encoder
12+
public let translations: [String: String]?
1213

1314
init(context: Context) {
14-
self.init(encoder: context.encoder)
15+
self.init(encoder: context.encoder, translations: context.translations)
1516
}
1617

17-
init(encoder: Encoder) {
18+
init(encoder: Encoder, translations: [String: String]? = nil) {
1819
self.encoder = encoder
20+
self.translations = translations
1921
}
2022
}

Sources/Liquid/Template.swift

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@ public final class Template {
2222

2323
private let fileSystem: FileSystem
2424

25-
public convenience init(sourceURL: URL, encoder: Encoder = Encoder(), environment: Environment = Environment()) throws {
25+
private let translations: [String: String]?
26+
27+
public convenience init(sourceURL: URL, encoder: Encoder = Encoder(), environment: Environment = Environment(), translations: [String: String]? = nil) throws {
2628
let source = try String(contentsOf: sourceURL)
2729
let fileSystem = LocalFileSystem(baseURL: sourceURL.deletingLastPathComponent())
2830
self.init(source: source, fileSystem: fileSystem, encoder: encoder, environment: environment)
@@ -43,13 +45,15 @@ public final class Template {
4345
self.environment = context.environment
4446
self.fileSystem = context.fileSystem
4547
self.filters = context.filters
48+
self.translations = context.translations
4649
self.tags = context.tags
4750
}
4851

49-
private init(source: String, fileSystem: FileSystem, encoder: Encoder, environment: Environment) {
52+
private init(source: String, fileSystem: FileSystem, encoder: Encoder, environment: Environment, translations: [String: String]? = nil) {
5053
self.source = source
5154
self.fileSystem = fileSystem
5255
self.environment = environment
56+
self.translations = translations
5357
self.encoder = encoder
5458

5559
tags["assign"] = Assign.init
@@ -88,7 +92,7 @@ public final class Template {
8892
}
8993

9094
public func render(values: [String: Value] = [:]) throws -> String {
91-
let context = Context(fileSystem: fileSystem, values: values, environment: environment, tags: tags, filters: filters, encoder: encoder)
95+
let context = Context(fileSystem: fileSystem, values: values, environment: environment, tags: tags, filters: filters, translations: translations, encoder: encoder)
9296
return try render(context: context)
9397
}
9498

Tests/LiquidTests/FilterTests.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,21 @@ final class FilterTests: XCTestCase {
271271
XCTAssertEqual(try Filters.dateFilter(value: Value("1152098955"), args: [Value("%m/%d/%Y")], kwargs: [:], context: FilterContext(encoder: encoder)), Value("07/05/2006"))
272272
}
273273

274+
func testTranslate() {
275+
var encoder = Encoder()
276+
encoder.locale = Locale(identifier: "en_US")
277+
278+
let sampleTranslationDict: [String: String] = [
279+
"x.files.main.characters": "%{argA} and %{argB}",
280+
"x.files.title": "The X-Files",
281+
]
282+
283+
let filterContext = FilterContext(encoder: encoder, translations: sampleTranslationDict)
284+
285+
XCTAssertEqual(try Filters.tFilter(value: Value("x.files.title"), args: [], kwargs: [:], context: filterContext), Value("The X-Files"))
286+
XCTAssertEqual(try Filters.tFilter(value: Value("x.files.main.characters"), args: [], kwargs: ["argA": Value("Fox Mulder"), "argB": Value("Dana Scully")], context: filterContext), Value("Fox Mulder and Dana Scully"))
287+
}
288+
274289
func testFilterArgs() {
275290
let echoFilter: FilterFunc = { (value, args, kwargs, encoder) -> Value in
276291
let strArgs = args.map { "\($0)" }.sorted()

0 commit comments

Comments
 (0)