summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authors9105947 <80697868+s9105947@users.noreply.github.com>2022-03-22 08:36:44 +0000
committerroot <root@delphi.lan>2022-08-08 21:08:57 +0200
commit07137f05a666c5b091200277d053a4671b130060 (patch)
tree53f60d0948a97b0d6152db2558193cc6f19aa31d
parent4d6505fd966558c1bd0948847f68f38d8c952299 (diff)
downloadmustache-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.json12
-rw-r--r--specs/comments.yml6
-rw-r--r--specs/~dynamic-names.yml49
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