feat(if): Support elif tags
This commit is contained in:
17
CHANGELOG.md
17
CHANGELOG.md
@@ -1,5 +1,22 @@
|
|||||||
# Stencil Changelog
|
# Stencil Changelog
|
||||||
|
|
||||||
|
## Master
|
||||||
|
|
||||||
|
### Enhancements
|
||||||
|
|
||||||
|
- `if` blocks may now contain else if (`elif`) conditions.
|
||||||
|
|
||||||
|
```html+django
|
||||||
|
{% if one or two and not three %}
|
||||||
|
one or two but not three
|
||||||
|
{% elif four %}
|
||||||
|
four
|
||||||
|
{% else %}
|
||||||
|
not one, two, or four
|
||||||
|
{% endif %}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## 0.8.0
|
## 0.8.0
|
||||||
|
|
||||||
### Breaking
|
### Breaking
|
||||||
|
|||||||
@@ -186,19 +186,30 @@ class IfNode : NodeType {
|
|||||||
var components = token.components()
|
var components = token.components()
|
||||||
components.removeFirst()
|
components.removeFirst()
|
||||||
|
|
||||||
var conditions: [IfCondition] = []
|
|
||||||
|
|
||||||
let expression = try parseExpression(components: components, tokenParser: parser)
|
let expression = try parseExpression(components: components, tokenParser: parser)
|
||||||
let nodes = try parser.parse(until(["endif", "else"]))
|
let nodes = try parser.parse(until(["endif", "elif", "else"]))
|
||||||
conditions.append(IfCondition(expression: expression, nodes: nodes))
|
var conditions: [IfCondition] = [
|
||||||
|
IfCondition(expression: expression, nodes: nodes)
|
||||||
|
]
|
||||||
|
|
||||||
guard let token = parser.nextToken() else {
|
var token = parser.nextToken()
|
||||||
throw TemplateSyntaxError("`endif` was not found.")
|
while let current = token, current.contents.hasPrefix("elif") {
|
||||||
|
var components = current.components()
|
||||||
|
components.removeFirst()
|
||||||
|
let expression = try parseExpression(components: components, tokenParser: parser)
|
||||||
|
|
||||||
|
let nodes = try parser.parse(until(["endif", "elif", "else"]))
|
||||||
|
token = parser.nextToken()
|
||||||
|
conditions.append(IfCondition(expression: expression, nodes: nodes))
|
||||||
}
|
}
|
||||||
|
|
||||||
if token.contents == "else" {
|
if let current = token, current.contents == "else" {
|
||||||
conditions.append(IfCondition(expression: nil, nodes: try parser.parse(until(["endif"]))))
|
conditions.append(IfCondition(expression: nil, nodes: try parser.parse(until(["endif"]))))
|
||||||
_ = parser.nextToken()
|
token = parser.nextToken()
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let current = token, current.contents == "endif" else {
|
||||||
|
throw TemplateSyntaxError("`endif` was not found.")
|
||||||
}
|
}
|
||||||
|
|
||||||
return IfNode(conditions: conditions)
|
return IfNode(conditions: conditions)
|
||||||
|
|||||||
@@ -48,6 +48,100 @@ func testIfNode() {
|
|||||||
try expect(falseNode?.text) == "false"
|
try expect(falseNode?.text) == "false"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$0.it("can parse an if with elif block") {
|
||||||
|
let tokens: [Token] = [
|
||||||
|
.block(value: "if value"),
|
||||||
|
.text(value: "true"),
|
||||||
|
.block(value: "elif something"),
|
||||||
|
.text(value: "some"),
|
||||||
|
.block(value: "else"),
|
||||||
|
.text(value: "false"),
|
||||||
|
.block(value: "endif")
|
||||||
|
]
|
||||||
|
|
||||||
|
let parser = TokenParser(tokens: tokens, environment: Environment())
|
||||||
|
let nodes = try parser.parse()
|
||||||
|
let node = nodes.first as? IfNode
|
||||||
|
|
||||||
|
let conditions = node?.conditions
|
||||||
|
try expect(conditions?.count) == 3
|
||||||
|
|
||||||
|
try expect(conditions?[0].nodes.count) == 1
|
||||||
|
let trueNode = conditions?[0].nodes.first as? TextNode
|
||||||
|
try expect(trueNode?.text) == "true"
|
||||||
|
|
||||||
|
try expect(conditions?[1].nodes.count) == 1
|
||||||
|
let elifNode = conditions?[1].nodes.first as? TextNode
|
||||||
|
try expect(elifNode?.text) == "some"
|
||||||
|
|
||||||
|
try expect(conditions?[2].nodes.count) == 1
|
||||||
|
let falseNode = conditions?[2].nodes.first as? TextNode
|
||||||
|
try expect(falseNode?.text) == "false"
|
||||||
|
}
|
||||||
|
|
||||||
|
$0.it("can parse an if with elif block without else") {
|
||||||
|
let tokens: [Token] = [
|
||||||
|
.block(value: "if value"),
|
||||||
|
.text(value: "true"),
|
||||||
|
.block(value: "elif something"),
|
||||||
|
.text(value: "some"),
|
||||||
|
.block(value: "endif")
|
||||||
|
]
|
||||||
|
|
||||||
|
let parser = TokenParser(tokens: tokens, environment: Environment())
|
||||||
|
let nodes = try parser.parse()
|
||||||
|
let node = nodes.first as? IfNode
|
||||||
|
|
||||||
|
let conditions = node?.conditions
|
||||||
|
try expect(conditions?.count) == 2
|
||||||
|
|
||||||
|
try expect(conditions?[0].nodes.count) == 1
|
||||||
|
let trueNode = conditions?[0].nodes.first as? TextNode
|
||||||
|
try expect(trueNode?.text) == "true"
|
||||||
|
|
||||||
|
try expect(conditions?[1].nodes.count) == 1
|
||||||
|
let elifNode = conditions?[1].nodes.first as? TextNode
|
||||||
|
try expect(elifNode?.text) == "some"
|
||||||
|
}
|
||||||
|
|
||||||
|
$0.it("can parse an if with multiple elif block") {
|
||||||
|
let tokens: [Token] = [
|
||||||
|
.block(value: "if value"),
|
||||||
|
.text(value: "true"),
|
||||||
|
.block(value: "elif something1"),
|
||||||
|
.text(value: "some1"),
|
||||||
|
.block(value: "elif something2"),
|
||||||
|
.text(value: "some2"),
|
||||||
|
.block(value: "else"),
|
||||||
|
.text(value: "false"),
|
||||||
|
.block(value: "endif")
|
||||||
|
]
|
||||||
|
|
||||||
|
let parser = TokenParser(tokens: tokens, environment: Environment())
|
||||||
|
let nodes = try parser.parse()
|
||||||
|
let node = nodes.first as? IfNode
|
||||||
|
|
||||||
|
let conditions = node?.conditions
|
||||||
|
try expect(conditions?.count) == 4
|
||||||
|
|
||||||
|
try expect(conditions?[0].nodes.count) == 1
|
||||||
|
let trueNode = conditions?[0].nodes.first as? TextNode
|
||||||
|
try expect(trueNode?.text) == "true"
|
||||||
|
|
||||||
|
try expect(conditions?[1].nodes.count) == 1
|
||||||
|
let elifNode = conditions?[1].nodes.first as? TextNode
|
||||||
|
try expect(elifNode?.text) == "some1"
|
||||||
|
|
||||||
|
try expect(conditions?[2].nodes.count) == 1
|
||||||
|
let elif2Node = conditions?[2].nodes.first as? TextNode
|
||||||
|
try expect(elif2Node?.text) == "some2"
|
||||||
|
|
||||||
|
try expect(conditions?[3].nodes.count) == 1
|
||||||
|
let falseNode = conditions?[3].nodes.first as? TextNode
|
||||||
|
try expect(falseNode?.text) == "false"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
$0.it("can parse an if with complex expression") {
|
$0.it("can parse an if with complex expression") {
|
||||||
let tokens: [Token] = [
|
let tokens: [Token] = [
|
||||||
.block(value: "if value == \"test\" and not name"),
|
.block(value: "if value == \"test\" and not name"),
|
||||||
|
|||||||
@@ -52,10 +52,12 @@ true the contents of the block are processed. Being true is defined as:
|
|||||||
|
|
||||||
.. code-block:: html+django
|
.. code-block:: html+django
|
||||||
|
|
||||||
{% if variable %}
|
{% if admin %}
|
||||||
The variable was found in the current context.
|
The user is an administrator.
|
||||||
|
{% elif user %}
|
||||||
|
A user is logged in.
|
||||||
{% else %}
|
{% else %}
|
||||||
The variable was not found.
|
No user was found.
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
Operators
|
Operators
|
||||||
|
|||||||
Reference in New Issue
Block a user