Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Feature/conditional block #22

Open
wants to merge 4 commits into from

5 participants

@wesen

I'm writing a compiler, and for efficiency purposes (and also template "clarity", in that i can see when a conditional is meant rather than iteration/lambda/new context/conditional), I decided to add a {{?test}} construct that can be used for conditionals. Also allows a kind of shortcut syntax {{?test}}then{{^test}}else{{/test}}.

let me know what you think.

@Zeelot

+1, having to make a new method for checking whether something is empty before iterating over it is quite annoying. (I hope this is what I think it is O_o)

@wesen

the way i implemented it is actually not for iteration. For iteration, usually, this should work, depending on the truthiness semantics of your implementation language

{{#product}}
Name: {{name}}
{{/product}}
{{^product}}
No products.
{{/product}}

Where is clear that you want to iterate over products. I use the above for things like:

{{?isLoggedIn}}Hello {{user}}.{{^isLoggedIn}}Login{{/isLoggedIn}}
@spullara

I've implemented the ? tag but didn't do the else. Looks like a reasonable idea to me.

@Baggz

+1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jul 19, 2011
  1. @wesen

    added conditionals

    wesen authored
  2. @pvande @wesen

    Failed partial lookups should be empty. Fixes #21.

    pvande authored wesen committed
  3. @wesen

    Reformat conditionals

    wesen authored
  4. @wesen

    Added conditionals

    wesen authored
This page is out of date. Refresh to see the latest.
View
1  specs/conditionals.json
@@ -0,0 +1 @@
+{"__ATTN__":"Do not edit this file; changes belong in the appropriate YAML file.","overview":"\nConditional tags are used to check for truthyness/falsyness\nvalues. They are similar to section, but don't iterate. Also, an\nelse case can be specified.\n\nWhen and Unless tags SHOULD be treated as standalone when\nappropriate.\n","tests":[{"name":"Truthy When","data":{"value":true},"expected":"This should be rendered.","template":"{{?value}}This should be rendered.{{/value}}","desc":"Truthy Whens should have their contents rendered."},{"name":"Falsy When","data":{"value":false},"expected":"","template":"{{?value}}This should not be rendered.{{/value}}","desc":"Falsy Whens should not have their contents rendered."},{"name":"Falsy Unless","data":{"value":false},"expected":"This should be rendered.","template":"{{^value}}This should be rendered.{{/value}}","desc":"Falsy Unless should have their contents rendered."},{"name":"Truthy Unless","data":{"value":true},"expected":"","template":"{{^value}}This should not be rendered.{{/value}}","desc":"Truthy Unless should not have their contents rendered."},{"name":"When Unless aka If Then Else","data":{"value":true},"expected":"YES","template":"{{?value}}YES{{^value}}NO{{/value}}","desc":"When and Unless can be chained"},{"name":"When Unless aka If Then Else with Falsy value","data":{"value":false},"expected":"NO","template":"{{?value}}YES{{^value}}NO{{/value}}","desc":"When and Unless can be chained"},{"name":"When Unless aka If Then Else can be inverted","data":{"value":false},"expected":"NO","template":"{{^value}}NO{{?value}}YES{{/value}}","desc":"When and Unless can be inverted"},{"name":"When should not iterate","data":{"list":[{"item":1},{"item":2},{"item":3}],"item":"item"},"expected":"item","template":"{{?list}}{{item}}{{/list}}","desc":"When is not a section"},{"name":"Surrounding Whitespace","data":{"boolean":true},"expected":" | \t|\t | \n","template":" | {{?boolean}}\t|\t{{/boolean}} | \n","desc":"Whens should not alter surrounding whitespace."},{"name":"Internal Whitespace","data":{"boolean":true},"expected":" | \n | \n","template":" | {{?boolean}} {{! Important Whitespace }}\n {{/boolean}} | \n","desc":"Whens should not alter internal whitespace."},{"name":"Indented Inline Sections","data":{"boolean":true},"expected":" YES\n GOOD\n","template":" {{?boolean}}YES{{/boolean}}\n {{?boolean}}GOOD{{/boolean}}\n","desc":"Single-line Whens should not alter surrounding whitespace."},{"name":"Standalone Lines","data":{"boolean":true},"expected":"| This Is\n|\n| A Line\n","template":"| This Is\n{{?boolean}}\n|\n{{/boolean}}\n| A Line\n","desc":"Standalone lines should be removed from the template."},{"name":"Indented Standalone Lines","data":{"boolean":true},"expected":"| This Is\n|\n| A Line\n","template":"| This Is\n {{?boolean}}\n|\n {{/boolean}}\n| A Line\n","desc":"Indented standalone lines should be removed from the template."},{"name":"Standalone Line Endings","data":{"boolean":true},"expected":"|\r\n|","template":"|\r\n{{?boolean}}\r\n{{/boolean}}\r\n|","desc":"\"\\r\\n\" should be considered a newline for standalone tags."},{"name":"Standalone Without Previous Line","data":{"boolean":true},"expected":"#\n/","template":" {{?boolean}}\n#{{/boolean}}\n/","desc":"Standalone tags should not require a newline to precede them."},{"name":"Standalone Without Newline","data":{"boolean":true},"expected":"#\n/\n","template":"#{{?boolean}}\n/\n {{/boolean}}","desc":"Standalone tags should not require a newline to follow them."},{"name":"Padding","data":{"boolean":true},"expected":"|=|","template":"|{{? boolean }}={{/ boolean }}|","desc":"Superfluous in-tag whitespace should be ignored."}]}
View
134 specs/conditionals.yml
@@ -0,0 +1,134 @@
+overview: |
+
+ Conditional tags are used to check for truthyness/falsyness
+ values. They are similar to section, but don't iterate. Also, an
+ else case can be specified.
+
+ When and Unless tags SHOULD be treated as standalone when
+ appropriate.
+tests:
+ - name: Truthy When
+ desc: Truthy Whens should have their contents rendered.
+ data: { value: true }
+ template: '{{?value}}This should be rendered.{{/value}}'
+ expected: 'This should be rendered.'
+
+ - name: Falsy When
+ desc: Falsy Whens should not have their contents rendered.
+ data: { value: false }
+ template: '{{?value}}This should not be rendered.{{/value}}'
+ expected: ''
+
+ - name: Falsy Unless
+ desc: Falsy Unless should have their contents rendered.
+ data: { value: false }
+ template: '{{^value}}This should be rendered.{{/value}}'
+ expected: 'This should be rendered.'
+
+ - name: Truthy Unless
+ desc: Truthy Unless should not have their contents rendered.
+ data: { value: true }
+ template: '{{^value}}This should not be rendered.{{/value}}'
+ expected: ''
+
+ - name: When Unless aka If Then Else
+ desc: When and Unless can be chained
+ data: { value: true }
+ template: '{{?value}}YES{{^value}}NO{{/value}}'
+ expected: 'YES'
+
+ - name: When Unless aka If Then Else with Falsy value
+ desc: When and Unless can be chained
+ data: { value: false }
+ template: '{{?value}}YES{{^value}}NO{{/value}}'
+ expected: 'NO'
+
+ - name: When Unless aka If Then Else can be inverted
+ desc: When and Unless can be inverted
+ data: { value: false }
+ template: '{{^value}}NO{{?value}}YES{{/value}}'
+ expected: 'NO'
+
+ # No iteration
+
+ - name: When should not iterate
+ desc: When is not a section
+ data:
+ list: [ { item: 1 }, { item: 2 }, { item: 3 } ]
+ item: 'item'
+ template: '{{?list}}{{item}}{{/list}}'
+ expected: 'item'
+
+ # Whitespace Sensitivy
+ - name: Surrounding Whitespace
+ desc: Whens should not alter surrounding whitespace.
+ data: { boolean: true }
+ template: " | {{?boolean}}\t|\t{{/boolean}} | \n"
+ expected: " | \t|\t | \n"
+
+ - name: Internal Whitespace
+ desc: Whens should not alter internal whitespace.
+ data: { boolean: true }
+ template: " | {{?boolean}} {{! Important Whitespace }}\n {{/boolean}} | \n"
+ expected: " | \n | \n"
+
+ - name: Indented Inline Sections
+ desc: Single-line Whens should not alter surrounding whitespace.
+ data: { boolean: true }
+ template: " {{?boolean}}YES{{/boolean}}\n {{?boolean}}GOOD{{/boolean}}\n"
+ expected: " YES\n GOOD\n"
+
+ - name: Standalone Lines
+ desc: Standalone lines should be removed from the template.
+ data: { boolean: true }
+ template: |
+ | This Is
+ {{?boolean}}
+ |
+ {{/boolean}}
+ | A Line
+ expected: |
+ | This Is
+ |
+ | A Line
+
+ - name: Indented Standalone Lines
+ desc: Indented standalone lines should be removed from the template.
+ data: { boolean: true }
+ template: |
+ | This Is
+ {{?boolean}}
+ |
+ {{/boolean}}
+ | A Line
+ expected: |
+ | This Is
+ |
+ | A Line
+
+ - name: Standalone Line Endings
+ desc: '"\r\n" should be considered a newline for standalone tags.'
+ data: { boolean: true }
+ template: "|\r\n{{?boolean}}\r\n{{/boolean}}\r\n|"
+ expected: "|\r\n|"
+
+ - name: Standalone Without Previous Line
+ desc: Standalone tags should not require a newline to precede them.
+ data: { boolean: true }
+ template: " {{?boolean}}\n#{{/boolean}}\n/"
+ expected: "#\n/"
+
+ - name: Standalone Without Newline
+ desc: Standalone tags should not require a newline to follow them.
+ data: { boolean: true }
+ template: "#{{?boolean}}\n/\n {{/boolean}}"
+ expected: "#\n/\n"
+
+ # Whitespace Insensitivity
+
+ - name: Padding
+ desc: Superfluous in-tag whitespace should be ignored.
+ data: { boolean: true }
+ template: '|{{? boolean }}={{/ boolean }}|'
+ expected: '|=|'
+
View
2  specs/partials.json
@@ -1 +1 @@
-{"__ATTN__":"Do not edit this file; changes belong in the appropriate YAML file.","overview":"Partial tags are used to expand an external template into the current\ntemplate.\n\nThe tag's content MUST be a non-whitespace character sequence NOT containing\nthe current closing delimiter.\n\nThis tag's content names the partial to inject. Set Delimiter tags MUST NOT\naffect the parsing of a partial. The partial MUST be rendered against the\ncontext stack local to the tag. If the named partial cannot be found, the\nempty string SHOULD be used instead, as in interpolations.\n\nPartial tags SHOULD be treated as standalone when appropriate. If this tag\nis used standalone, any whitespace preceding the tag should treated as\nindentation, and prepended to each line of the partial before rendering.\n","tests":[{"name":"Basic Behavior","data":{},"expected":"\"from partial\"","template":"\"{{>text}}\"","desc":"The greater-than operator should expand to the named partial.","partials":{"text":"from partial"}},{"name":"Failed Lookup","data":{},"expected":"\"from partial\"","template":"\"{{>text}}\"","desc":"The empty string should be used when the named partial is not found.","partials":{}},{"name":"Context","data":{"text":"content"},"expected":"\"*content*\"","template":"\"{{>partial}}\"","desc":"The greater-than operator should operate within the current context.","partials":{"partial":"*{{text}}*"}},{"name":"Recursion","data":{"content":"X","nodes":[{"content":"Y","nodes":[]}]},"expected":"X<Y<>>","template":"{{>node}}","desc":"The greater-than operator should properly recurse.","partials":{"node":"{{content}}<{{#nodes}}{{>node}}{{/nodes}}>"}},{"name":"Surrounding Whitespace","data":{},"expected":"| \t|\t |","template":"| {{>partial}} |","desc":"The greater-than operator should not alter surrounding whitespace.","partials":{"partial":"\t|\t"}},{"name":"Inline Indentation","data":{"data":"|"},"expected":" | >\n>\n","template":" {{data}} {{> partial}}\n","desc":"Whitespace should be left untouched.","partials":{"partial":">\n>"}},{"name":"Standalone Line Endings","data":{},"expected":"|\r\n>|","template":"|\r\n{{>partial}}\r\n|","desc":"\"\\r\\n\" should be considered a newline for standalone tags.","partials":{"partial":">"}},{"name":"Standalone Without Previous Line","data":{},"expected":" >\n >>","template":" {{>partial}}\n>","desc":"Standalone tags should not require a newline to precede them.","partials":{"partial":">\n>"}},{"name":"Standalone Without Newline","data":{},"expected":">\n >\n >","template":">\n {{>partial}}","desc":"Standalone tags should not require a newline to follow them.","partials":{"partial":">\n>"}},{"name":"Standalone Indentation","data":{"content":"<\n->"},"expected":"\\\n |\n <\n->\n |\n/\n","template":"\\\n {{>partial}}\n/\n","desc":"Each line of the partial should be indented before rendering.","partials":{"partial":"|\n{{{content}}}\n|\n"}},{"name":"Padding Whitespace","data":{"boolean":true},"expected":"|[]|","template":"|{{> partial }}|","desc":"Superfluous in-tag whitespace should be ignored.","partials":{"partial":"[]"}}]}
+{"__ATTN__":"Do not edit this file; changes belong in the appropriate YAML file.","overview":"Partial tags are used to expand an external template into the current\ntemplate.\n\nThe tag's content MUST be a non-whitespace character sequence NOT containing\nthe current closing delimiter.\n\nThis tag's content names the partial to inject. Set Delimiter tags MUST NOT\naffect the parsing of a partial. The partial MUST be rendered against the\ncontext stack local to the tag. If the named partial cannot be found, the\nempty string SHOULD be used instead, as in interpolations.\n\nPartial tags SHOULD be treated as standalone when appropriate. If this tag\nis used standalone, any whitespace preceding the tag should treated as\nindentation, and prepended to each line of the partial before rendering.\n","tests":[{"name":"Basic Behavior","data":{},"expected":"\"from partial\"","template":"\"{{>text}}\"","desc":"The greater-than operator should expand to the named partial.","partials":{"text":"from partial"}},{"name":"Failed Lookup","data":{},"expected":"\"\"","template":"\"{{>text}}\"","desc":"The empty string should be used when the named partial is not found.","partials":{}},{"name":"Context","data":{"text":"content"},"expected":"\"*content*\"","template":"\"{{>partial}}\"","desc":"The greater-than operator should operate within the current context.","partials":{"partial":"*{{text}}*"}},{"name":"Recursion","data":{"content":"X","nodes":[{"content":"Y","nodes":[]}]},"expected":"X<Y<>>","template":"{{>node}}","desc":"The greater-than operator should properly recurse.","partials":{"node":"{{content}}<{{#nodes}}{{>node}}{{/nodes}}>"}},{"name":"Surrounding Whitespace","data":{},"expected":"| \t|\t |","template":"| {{>partial}} |","desc":"The greater-than operator should not alter surrounding whitespace.","partials":{"partial":"\t|\t"}},{"name":"Inline Indentation","data":{"data":"|"},"expected":" | >\n>\n","template":" {{data}} {{> partial}}\n","desc":"Whitespace should be left untouched.","partials":{"partial":">\n>"}},{"name":"Standalone Line Endings","data":{},"expected":"|\r\n>|","template":"|\r\n{{>partial}}\r\n|","desc":"\"\\r\\n\" should be considered a newline for standalone tags.","partials":{"partial":">"}},{"name":"Standalone Without Previous Line","data":{},"expected":" >\n >>","template":" {{>partial}}\n>","desc":"Standalone tags should not require a newline to precede them.","partials":{"partial":">\n>"}},{"name":"Standalone Without Newline","data":{},"expected":">\n >\n >","template":">\n {{>partial}}","desc":"Standalone tags should not require a newline to follow them.","partials":{"partial":">\n>"}},{"name":"Standalone Indentation","data":{"content":"<\n->"},"expected":"\\\n |\n <\n->\n |\n/\n","template":"\\\n {{>partial}}\n/\n","desc":"Each line of the partial should be indented before rendering.","partials":{"partial":"|\n{{{content}}}\n|\n"}},{"name":"Padding Whitespace","data":{"boolean":true},"expected":"|[]|","template":"|{{> partial }}|","desc":"Superfluous in-tag whitespace should be ignored.","partials":{"partial":"[]"}}]}
View
2  specs/partials.yml
@@ -26,7 +26,7 @@ tests:
data: { }
template: '"{{>text}}"'
partials: { }
- expected: '"from partial"'
+ expected: '""'
- name: Context
desc: The greater-than operator should operate within the current context.
Something went wrong with that request. Please try again.