|
1 | 1 | overview: | |
2 | 2 | Section tags and End Section tags are used in combination to wrap a section |
3 | | - of the template for iteration |
| 3 | + of the template for iteration. |
4 | 4 |
|
5 | 5 | These tags' content MUST be a non-whitespace character sequence NOT |
6 | 6 | containing the current closing delimiter; each Section tag MUST be followed |
7 | 7 | by an End Section tag with the same content within the same section. |
8 | 8 |
|
9 | 9 | This tag's content names the data to replace the tag. Name resolution is as |
10 | 10 | follows: |
11 | | - 1) Split the name on periods; the first part is the name to resolve, any |
| 11 | + 1) If the name is a single period (.), the data is the item currently |
| 12 | + sitting atop the context stack. Skip the rest of these steps. |
| 13 | + 2) Split the name on periods; the first part is the name to resolve, any |
12 | 14 | remaining parts should be retained. |
13 | | - 2) Walk the context stack from top to bottom, finding the first context |
| 15 | + 3) Walk the context stack from top to bottom, finding the first context |
14 | 16 | that is a) a hash containing the name as a key OR b) an object responding |
15 | 17 | to a method with the given name. |
16 | | - 3) If the context is a hash, the data is the value associated with the |
| 18 | + 4) If the context is a hash, the data is the value associated with the |
17 | 19 | name. |
18 | | - 4) If the context is an object and the method with the given name has an |
| 20 | + 5) If the context is an object and the method with the given name has an |
19 | 21 | arity of 1, the method SHOULD be called with a String containing the |
20 | 22 | unprocessed contents of the sections; the data is the value returned. |
21 | | - 5) Otherwise, the data is the value returned by calling the method with |
| 23 | + 6) Otherwise, the data is the value returned by calling the method with |
22 | 24 | the given name. |
23 | | - 6) If any name parts were retained in step 1, each should be resolved |
| 25 | + 7) If any name parts were retained in step 1, each should be resolved |
24 | 26 | against a context stack containing only the result from the former |
25 | 27 | resolution. If any part fails resolution, the result should be considered |
26 | 28 | falsey, and should interpolate as the empty string. |
| 29 | +
|
27 | 30 | If the data is not of a list type, it is coerced into a list as follows: if |
28 | 31 | the data is truthy (e.g. `!!data == true`), use a single-element list |
29 | 32 | containing the data, otherwise use an empty list. |
@@ -206,6 +209,33 @@ tests: |
206 | 209 | template: '"{{#list}}({{#.}}{{.}}{{/.}}){{/list}}"' |
207 | 210 | expected: '"(123)(abc)"' |
208 | 211 |
|
| 212 | + - name: Implicit Iterator - HTML Escaping |
| 213 | + desc: Implicit iterators with basic interpolation should be HTML escaped. |
| 214 | + data: |
| 215 | + list: [ '&', '"', '<', '>' ] |
| 216 | + template: '"{{#list}}({{.}}){{/list}}"' |
| 217 | + expected: '"(&)(")(<)(>)"' |
| 218 | + |
| 219 | + - name: Implicit Iterator - Triple mustache |
| 220 | + desc: Implicit iterators in triple mustache should interpolate without HTML escaping. |
| 221 | + data: |
| 222 | + list: [ '&', '"', '<', '>' ] |
| 223 | + template: '"{{#list}}({{{.}}}){{/list}}"' |
| 224 | + expected: '"(&)(")(<)(>)"' |
| 225 | + |
| 226 | + - name: Implicit Iterator - Ampersand |
| 227 | + desc: Implicit iterators in an Ampersand tag should interpolate without HTML escaping. |
| 228 | + data: |
| 229 | + list: [ '&', '"', '<', '>' ] |
| 230 | + template: '"{{#list}}({{&.}}){{/list}}"' |
| 231 | + expected: '"(&)(")(<)(>)"' |
| 232 | + |
| 233 | + - name: Implicit Iterator - Root-level |
| 234 | + desc: Implicit iterators should work on root-level lists. |
| 235 | + data: [ { value: 'a' }, { value: 'b' } ] |
| 236 | + template: '"{{#.}}({{value}}){{/.}}"' |
| 237 | + expected: '"(a)(b)"' |
| 238 | + |
209 | 239 | # Dotted Names |
210 | 240 |
|
211 | 241 | - name: Dotted Names - Truthy |
|
0 commit comments