diff options
author | s9105947 <80697868+s9105947@users.noreply.github.com> | 2022-03-22 08:36:44 +0000 |
---|---|---|
committer | root <root@delphi.lan> | 2022-08-08 21:08:57 +0200 |
commit | 07137f05a666c5b091200277d053a4671b130060 (patch) | |
tree | 53f60d0948a97b0d6152db2558193cc6f19aa31d | |
parent | 4d6505fd966558c1bd0948847f68f38d8c952299 (diff) | |
download | mustache-spec-07137f05a666c5b091200277d053a4671b130060.tar.gz |
Adding a test: comment content colliding with variable (squashed) (coauthored)
Currently, an implementation treating comments as undefined variables
successfully passes all tests, because both undefined variables and
comments render to empty string.
This clarifies the behavior: A comment MUST NOT render into anything,
under any circumstances. This includes the case where a variable with
the same name as the comment content is defined.
The test data is designed in a way to trigger any possible name
collision, including white spaces, a leading exclamation mark (!).
Update specs/~dynamic-names.yml
Co-authored-by: Julian Gonggrijp <dev@juliangonggrijp.com>
Update specs/~dynamic-names.yml
Co-authored-by: Julian Gonggrijp <dev@juliangonggrijp.com>
Update specs/~dynamic-names.yml
Co-authored-by: Julian Gonggrijp <dev@juliangonggrijp.com>
Update specs/~dynamic-names.yml
Co-authored-by: Julian Gonggrijp <dev@juliangonggrijp.com>
Update specs/~dynamic-names.yml
Co-authored-by: Julian Gonggrijp <dev@juliangonggrijp.com>
Update specs/~dynamic-names.yml
Co-authored-by: Julian Gonggrijp <dev@juliangonggrijp.com>
Update specs/~dynamic-names.yml
Co-authored-by: Julian Gonggrijp <dev@juliangonggrijp.com>
Update specs/~dynamic-names.yml
Co-authored-by: Julian Gonggrijp <dev@juliangonggrijp.com>
Update specs/~dynamic-names.yml
Co-authored-by: Julian Gonggrijp <dev@juliangonggrijp.com>
Update specs/~dynamic-names.yml
Co-authored-by: Julian Gonggrijp <dev@juliangonggrijp.com>
-rw-r--r-- | specs/comments.json | 12 | ||||
-rw-r--r-- | specs/comments.yml | 6 | ||||
-rw-r--r-- | specs/~dynamic-names.yml | 49 |
3 files changed, 43 insertions, 24 deletions
diff --git a/specs/comments.json b/specs/comments.json index 60a4929..924ed46 100644 --- a/specs/comments.json +++ b/specs/comments.json @@ -89,6 +89,18 @@ }, "template": "12345 {{! Comment Block! }} 67890", "expected": "12345 67890" + }, + { + "name": "Variable Name Collision", + "desc": "Comments must never render, even if variable with same name exists.", + "data": { + "! comment": 1, + "! comment ": 2, + "!comment": 3, + "comment": 4 + }, + "template": "comments never show: >{{! comment }}<", + "expected": "comments never show: ><" } ] } diff --git a/specs/comments.yml b/specs/comments.yml index 7b14c7f..3bad09f 100644 --- a/specs/comments.yml +++ b/specs/comments.yml @@ -101,3 +101,9 @@ tests: data: { } template: '12345 {{! Comment Block! }} 67890' expected: '12345 67890' + + - name: Variable Name Collision + desc: Comments must never render, even if variable with same name exists. + data: { '! comment': 1, '! comment ': 2, '!comment': 3, 'comment': 4} + template: 'comments never show: >{{! comment }}<' + expected: 'comments never show: ><' diff --git a/specs/~dynamic-names.yml b/specs/~dynamic-names.yml index 30edc39..d980717 100644 --- a/specs/~dynamic-names.yml +++ b/specs/~dynamic-names.yml @@ -2,36 +2,36 @@ overview: | Rationale: this special notation was introduced primarily to allow the dynamic loading of partials. The main advantage that this notation offers is to allow dynamic loading of partials, which is particularly useful in cases where - polymorphic data needs to be rendered in different ways, cases which would + polymorphic data needs to be rendered in different ways. Such cases would otherwise be possible to render only with solutions that are convoluted, inefficient, or both. Example. Let's consider the following data: - items: [ - { content: 'Hello, World!' }, - { url: 'http://example.com/foo.jpg' }, - { content: 'Some text' }, - { content: 'Some other text' }, - { url: 'http://example.com/bar.jpg' }, - { url: 'http://example.com/baz.jpg' }, - { content: 'Last text here' } - ] - The goal is to render the different types of items in different ways: the + items: [ + { content: 'Hello, World!' }, + { url: 'http://example.com/foo.jpg' }, + { content: 'Some text' }, + { content: 'Some other text' }, + { url: 'http://example.com/bar.jpg' }, + { url: 'http://example.com/baz.jpg' }, + { content: 'Last text here' } + ] + The goal is to render the different types of items in different ways. The items having a key named `content` should be rendered with the template `text.mustache` and the items having a key named `url` should be rendered with the template `image.mustache`: - text.mustache: - {{!image.mustache}} - <img src="{{url}}"/> - image.mustache: - {{!text.mustache}} - {{content}} + + {{!image.mustache}} + <img src="{{url}}"/> + + {{!text.mustache}} + {{content}} There are already several ways to achieve this goal, here below are illustrated and discussed the most significant solutions to this problem. ## Using Pre-Processing The idea is to use a secondary templating mechanism to dynamically generate the template that will be rendered. - The template that our secondary templating mechanism generates should look + The template that our secondary templating mechanism generates might look like this: {{!template.mustache}} {{items.1.content}} @@ -46,7 +46,7 @@ overview: | The drawbacks are the rendering speed and the complexity that the secondary templating mechanism requires. ## Using Lambdas - The idea is to inject into the data functions that will be later called from + The idea is to inject functions into the data that will be later called from the template. This way the data will look like this: items: [ @@ -85,11 +85,11 @@ overview: | {{{html}}} {{/items}} The advantage this solution offers is to have a light main template. - The drawback is that the data needs to embed logic and template tags tags in + The drawback is that the data needs to embed logic and template tags in it. - ## Using If Blocks - The idea is to put some logic into the main template so it can dynamically - load templates: + ## Using If-Else Blocks + The idea is to put some logic into the main template so it can select the + templates at rendering time: {{!template.mustache}} {{#items}} {{#url}} @@ -100,7 +100,8 @@ overview: | {{/content}} {{/items}} The main advantage of this solution is that it works without adding any - overhead fields to the data. + overhead fields to the data. It also documents which external templates are + appropriate for expansion in this position. The drawback is that this solution isn't optimal for heterogeneous data sets as the main template grows linearly with the number of polymorphic variants. ## Using Dynamic Names |