Path Expressions
A path expression is a list of ids separated by dots. It is resolved by recursively retrieving the property matching the id of the current input object.
{{person.name}}
{ "person": { "name": "Max" } }
Max
{
"type": "Program",
"body": [
{
"type": "MustacheStatement",
"escaped": true,
"params": [],
"path": {
"type": "PathExpression",
"original": "person.name",
"data": false,
"depth": 0,
"parts": ["person", "name"],
"loc": {
"start": { "line": 1, "column": 2 },
"end": { "line": 1, "column": 13 }
}
},
"strip": { "open": false, "close": false },
"loc": {
"start": { "line": 1, "column": 0 },
"end": { "line": 1, "column": 15 }
}
}
],
"strip": {},
"loc": {
"start": { "line": 1, "column": 0 },
"end": { "line": 1, "column": 15 }
}
}
If the id matches no property of the object, an empty string is returned. (TODO: Or does it return “undefined” or “null”, which is converted to an empty string by the mustache-statements?)
{{person.name}}
{ "person": "Max" }
{
"type": "Program",
"body": [
{
"type": "MustacheStatement",
"escaped": true,
"params": [],
"path": {
"type": "PathExpression",
"original": "person.name",
"data": false,
"depth": 0,
"parts": ["person", "name"],
"loc": {
"start": { "line": 1, "column": 2 },
"end": { "line": 1, "column": 13 }
}
},
"strip": { "open": false, "close": false },
"loc": {
"start": { "line": 1, "column": 0 },
"end": { "line": 1, "column": 15 }
}
}
],
"strip": {},
"loc": {
"start": { "line": 1, "column": 0 },
"end": { "line": 1, "column": 15 }
}
}
If a prefix of the path expressions that resolves to nothing, the result is also an empty string.
{{person.name}}{{{person.name}}}
{}
{
"type": "Program",
"body": [
{
"type": "MustacheStatement",
"escaped": true,
"params": [],
"path": {
"type": "PathExpression",
"original": "person.name",
"data": false,
"depth": 0,
"parts": ["person", "name"],
"loc": {
"start": { "line": 1, "column": 2 },
"end": { "line": 1, "column": 13 }
}
},
"strip": { "open": false, "close": false },
"loc": {
"start": { "line": 1, "column": 0 },
"end": { "line": 1, "column": 15 }
}
},
{
"type": "MustacheStatement",
"escaped": false,
"params": [],
"path": {
"type": "PathExpression",
"original": "person.name",
"data": false,
"depth": 0,
"parts": ["person", "name"],
"loc": {
"start": { "line": 1, "column": 18 },
"end": { "line": 1, "column": 29 }
}
},
"strip": { "open": false, "close": false },
"loc": {
"start": { "line": 1, "column": 15 },
"end": { "line": 1, "column": 32 }
}
}
],
"strip": {},
"loc": {
"start": { "line": 1, "column": 0 },
"end": { "line": 1, "column": 32 }
}
}
A path expression may contain ids separated by slashes
{{person/name}}
{ "person": { "name": "Max" } }
Max
{
"type": "Program",
"body": [
{
"type": "MustacheStatement",
"escaped": true,
"params": [],
"path": {
"type": "PathExpression",
"original": "person/name",
"data": false,
"depth": 0,
"parts": ["person", "name"],
"loc": {
"start": { "line": 1, "column": 2 },
"end": { "line": 1, "column": 13 }
}
},
"strip": { "open": false, "close": false },
"loc": {
"start": { "line": 1, "column": 0 },
"end": { "line": 1, "column": 15 }
}
}
],
"strip": {},
"loc": {
"start": { "line": 1, "column": 0 },
"end": { "line": 1, "column": 15 }
}
}
Dots and slashes may be mixed.
{{who.person/name}}
{ "who": { "person": { "name": "Max" } } }
Max
{
"type": "Program",
"body": [
{
"type": "MustacheStatement",
"escaped": true,
"params": [],
"path": {
"type": "PathExpression",
"original": "who.person/name",
"data": false,
"depth": 0,
"parts": ["who", "person", "name"],
"loc": {
"start": { "line": 1, "column": 2 },
"end": { "line": 1, "column": 17 }
}
},
"strip": { "open": false, "close": false },
"loc": {
"start": { "line": 1, "column": 0 },
"end": { "line": 1, "column": 19 }
}
}
],
"strip": {},
"loc": {
"start": { "line": 1, "column": 0 },
"end": { "line": 1, "column": 19 }
}
}
Literal segments
Identifiers may contain any unicode character except for the following.
It may be wise to allow multiple templates in such a test-case. Otherwise we need one file per illegal character.
Ids with special charactares must be wrapped in [
and ]
. It may than not include a closing ]
.
{{['].[ ].[0]}}
{ "'": { " ": ["success"] } }
success
{
"type": "Program",
"body": [
{
"type": "MustacheStatement",
"escaped": true,
"params": [],
"path": {
"type": "PathExpression",
"original": "['].[ ].[0]",
"data": false,
"depth": 0,
"parts": ["'", " ", "0"],
"loc": {
"start": { "line": 1, "column": 2 },
"end": { "line": 1, "column": 13 }
}
},
"strip": { "open": false, "close": false },
"loc": {
"start": { "line": 1, "column": 0 },
"end": { "line": 1, "column": 15 }
}
}
],
"strip": {},
"loc": {
"start": { "line": 1, "column": 0 },
"end": { "line": 1, "column": 15 }
}
}
{
"type": "Program",
"body": [
{
"type": "MustacheStatement",
"escaped": true,
"params": [],
"path": {
"type": "PathExpression",
"original": "'. .0",
"data": false,
"depth": 0,
"parts": ["'", " ", "0"],
"loc": {
"start": { "line": 1, "column": 2 },
"end": { "line": 1, "column": 13 }
}
},
"strip": { "open": false, "close": false },
"loc": {
"start": { "line": 1, "column": 0 },
"end": { "line": 1, "column": 15 }
}
}
],
"strip": {},
"loc": {
"start": { "line": 1, "column": 0 },
"end": { "line": 1, "column": 15 }
}
}
TODO: Quotes to allow invalid chars
The original Handlebars parser also allows Literal expressions to be the
In https://github.com/handlebars-lang/docs/pull/119 it was pointed out that the following also works
{{"id containing spaces"}}
{{"id containing spaces"}}
but the following does not
{{ 'id containing spaces'.moreProp}}
{{ "id containing spaces".moreProps}}
This is because the {{ 'id containing spaces' }}
interpreted by the parser as LiteralString, where quotes are allowed, but
{{ 'id containing spaces'.moreProp}}
is a contains a PathExpressions, where quotes aren’t allowed.
This could be considered a bug in the parser.