Skip to content

Commit

Permalink
Fixed using spaces in filter expressions and variables lists (#178)
Browse files Browse the repository at this point in the history
* fixed using spaces in filter expression

* fixed breaking variables lists and filters by spaces

* simplified smartJoin

* avoid force unwrap
  • Loading branch information
ilyapuchka authored May 13, 2018
1 parent d935f65 commit 39ed9aa
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 11 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,15 @@
[Yonas Kolb](https://github.com/yonaskolb)
[#394](https://github.com/stencilproject/Stencil/pull/214)

- Adds support for using spaces in filter expression
[Ilya Puchka](https://github.com/yonaskolb)
[#178](https://github.com/stencilproject/Stencil/pull/178)

### Bug Fixes

- Fixed using quote as a filter parameter
[Ilya Puchka](https://github.com/yonaskolb)
[#210](https://github.com/stencilproject/Stencil/pull/210)


## 0.11.0 (2018-04-04)
Expand Down
2 changes: 1 addition & 1 deletion Sources/ForTag.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class ForNode : NodeType {
let loopVariables = components[1].characters
.split(separator: ",")
.map(String.init)
.map { $0.trimmingCharacters(in: CharacterSet.whitespaces) }
.map { $0.trim(character: " ") }

var emptyNodes = [NodeType]()

Expand Down
19 changes: 17 additions & 2 deletions Sources/Tokenizer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,21 @@ extension String {
var singleQuoteCount = 0
var doubleQuoteCount = 0

let specialCharacters = ",|:"
func appendWord(_ word: String) {
if components.count > 0 {
if let precedingChar = components.last?.characters.last, specialCharacters.characters.contains(precedingChar) {
components[components.count-1] += word
} else if specialCharacters.contains(word) {
components[components.count-1] += word
} else {
components.append(word)
}
} else {
components.append(word)
}
}

for character in self.characters {
if character == "'" { singleQuoteCount += 1 }
else if character == "\"" { doubleQuoteCount += 1 }
Expand All @@ -19,7 +34,7 @@ extension String {
if separate != separator {
word.append(separate)
} else if (singleQuoteCount % 2 == 0 || doubleQuoteCount % 2 == 0) && !word.isEmpty {
components.append(word)
appendWord(word)
word = ""
}

Expand All @@ -33,7 +48,7 @@ extension String {
}

if !word.isEmpty {
components.append(word)
appendWord(word)
}

return components
Expand Down
4 changes: 2 additions & 2 deletions Sources/Variable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -209,11 +209,11 @@ extension Dictionary : Normalizable {

func parseFilterComponents(token: String) -> (String, [Variable]) {
var components = token.smartSplit(separator: ":")
let name = components.removeFirst()
let name = components.removeFirst().trim(character: " ")
let variables = components
.joined(separator: ":")
.smartSplit(separator: ",")
.map { Variable($0) }
.map { Variable($0.trim(character: " ")) }
return (name, variables)
}

Expand Down
6 changes: 3 additions & 3 deletions Tests/StencilTests/FilterSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ func testFilter() {
}

$0.it("allows whitespace in expression") {
let template = Template(templateString: "{{ name | uppercase }}")
let result = try template.render(Context(dictionary: ["name": "kyle"]))
try expect(result) == "KYLE"
let template = Template(templateString: "{{ value | join : \", \" }}")
let result = try template.render(Context(dictionary: ["value": ["One", "Two"]]))
try expect(result) == "One, Two"
}

$0.it("throws when you pass arguments to simple filter") {
Expand Down
6 changes: 3 additions & 3 deletions Tests/StencilTests/ForNodeSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ func testForNode() {
try expect(try node.render(context)) == "empty"
}

$0.it("can render a filter") {
let templateString = "{% for article in ars|default:articles %}" +
$0.it("can render a filter with spaces") {
let templateString = "{% for article in ars | default: a, b , articles %}" +
"- {{ article.title }} by {{ article.author }}.\n" +
"{% endfor %}\n"

Expand Down Expand Up @@ -182,7 +182,7 @@ func testForNode() {
}

$0.it("can iterate over dictionary") {
let templateString = "{% for key,value in dict %}" +
let templateString = "{% for key, value in dict %}" +
"{{ key }}: {{ value }}," +
"{% endfor %}"

Expand Down

0 comments on commit 39ed9aa

Please sign in to comment.