Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The specification does not specify how to handle tags with periods in them #179

Closed
simon-ess opened this issue Nov 21, 2023 · 5 comments · Fixed by #180
Closed

The specification does not specify how to handle tags with periods in them #179

simon-ess opened this issue Nov 21, 2023 · 5 comments · Fixed by #180
Labels
debate choice that involves preference documentation human-oriented text could be improved

Comments

@simon-ess
Copy link
Contributor

Consider the following data:

{"a.b": "c"}

and the template

{{ a.b }}

What should this render? According to the two python implementations (https://github.com/noahmorrison/chevron, https://github.com/defunkt/pystache) I have seen, it renders a blank, since a.b in the template is looking for a structure of the form

{"a": {"b": "c"}}

However, the java implementation we use (https://github.com/spullara/mustache.java) the output instead is

c

In fact, the same is the case if you use input data such as

{"a":
  {"b": "d"},
 "a.b": "c"
}

where the key a.b overrides the nested structure (which seems like the wrong choice to me, given the options).

The problem here is that this seems to be undefined behaviour: the spec never defines what to do with keys that have periods in them, which leaves individual engines up to their own devices on how to handle it. There is an open issue which implies that one should not do this, but it is not explicit: #67 (comment)

It would be good to have this specified, to ensure consistent behaviour between various engines.

@jgonggrijp
Copy link
Member

Is this really unspecified? I mean, the interpolation and section specs are rather explicit about how dotted names should be resolved. I don't think the specs allow for mustache.java's behavior.

@simon-ess
Copy link
Contributor Author

Well, see spullara/mustache.java#297 (comment) for their response to this issue.

The behaviour is, in my opinion, undefined as there is no formal specification that I could find for what a well-formed key should be. All of the keys are alphanumeric strings with no special characters, but it doesn't say that those are the only allowed characters, which in theory permits keys of the form a.b.c.d.

@simon-ess
Copy link
Contributor Author

(It's worth noting that we ran into this as we were using a filename as a key, which worked as we naïvely expected in the java implementation, but then broke when we switched to a python engine)

@jgonggrijp
Copy link
Member

These are the relevant parts of the interpolation spec. The section spec has similar wording and tests.

This tag's content names the data to replace the tag. A single period (`.`)
indicates that the item currently sitting atop the context stack should be
used; otherwise, name resolution is as follows:
1) Split the name on periods; the first part is the name to resolve, any
remaining parts should be retained.
2) Walk the context stack from top to bottom, finding the first context
that is a) a hash containing the name as a key OR b) an object responding
to a method with the given name.
3) If the context is a hash, the data is the value associated with the
name.
4) If the context is an object, the data is the value returned by the
method with the given name.
5) If any name parts were retained in step 1, each should be resolved
against a context stack containing only the result from the former
resolution. If any part fails resolution, the result should be considered
falsey, and should interpolate as the empty string.

# Dotted Names
- name: Dotted Names - Basic Interpolation
desc: Dotted names should be considered a form of shorthand for sections.
data: { person: { name: 'Joe' } }
template: '"{{person.name}}" == "{{#person}}{{name}}{{/person}}"'
expected: '"Joe" == "Joe"'
- name: Dotted Names - Triple Mustache Interpolation
desc: Dotted names should be considered a form of shorthand for sections.
data: { person: { name: 'Joe' } }
template: '"{{{person.name}}}" == "{{#person}}{{{name}}}{{/person}}"'
expected: '"Joe" == "Joe"'
- name: Dotted Names - Ampersand Interpolation
desc: Dotted names should be considered a form of shorthand for sections.
data: { person: { name: 'Joe' } }
template: '"{{&person.name}}" == "{{#person}}{{&name}}{{/person}}"'
expected: '"Joe" == "Joe"'
- name: Dotted Names - Arbitrary Depth
desc: Dotted names should be functional to any level of nesting.
data:
a: { b: { c: { d: { e: { name: 'Phil' } } } } }
template: '"{{a.b.c.d.e.name}}" == "Phil"'
expected: '"Phil" == "Phil"'
- name: Dotted Names - Broken Chains
desc: Any falsey value prior to the last part of the name should yield ''.
data:
a: { }
template: '"{{a.b.c}}" == ""'
expected: '"" == ""'
- name: Dotted Names - Broken Chain Resolution
desc: Each part of a dotted name should resolve only against its parent.
data:
a: { b: { } }
c: { name: 'Jim' }
template: '"{{a.b.c.name}}" == ""'
expected: '"" == ""'
- name: Dotted Names - Initial Resolution
desc: The first part of a dotted name should resolve as any other name.
data:
a: { b: { c: { d: { e: { name: 'Phil' } } } } }
b: { c: { d: { e: { name: 'Wrong' } } } }
template: '"{{#a}}{{b.c.d.e.name}}{{/a}}" == "Phil"'
expected: '"Phil" == "Phil"'
- name: Dotted Names - Context Precedence
desc: Dotted names should be resolved against former resolutions.
data:
a: { b: { } }
b: { c: 'ERROR' }
template: '{{#a}}{{b.c}}{{/a}}'
expected: ''

@simon-ess
Copy link
Contributor Author

Ah, fair point, there is a description there. However, there are no tests that actually verify this. It might be good to add a test of the form

  - name: Dotted keys
    desc: Dotted keys should not be treated as standalone keys
    data:
      a.b: c
    template: '"{{a.b}}" == ""'
    expected: '"" == ""'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
debate choice that involves preference documentation human-oriented text could be improved
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants