Expressions
In addition to different magic tag types, stache supports different expression types. These can be used in various combinations to call helper methods or viewModel methods. The following is an example of all the expressions combined:
{{helper key1 "string" method(key2, 1, prop1=key3) prop2=key4}}
There are 6 expression types stache supports:
- Literal expressions like
{{"string"}}
- KeyLookup expressions like
{{key}}
- Hash expressions like
{{prop=key}}
- Call expressions like
{{method(arg)}}
- Helper expressions like
{{helper arg}}
- Bracket expressions like
{{[key]}}
Literal expressions
A Literal Expression specifies JS primitive values like:
- Strings
"strings"
- Numbers
5
- Booleans
true
orfalse
- And
null
orundefined
They are usually passed as arguments to Call or Helper expressions like:
{{pluralize "dog" 2}}
{{task.filter("completed", true)}}
KeyLookup expressions
A KeyLookup Expression specifies a value in the scope or HelperOptions scope that will be looked up. KeyLookup expressions can be the entire stache expression like:
{{key}}
Or they can make up the method, helper, arguments, and hash value parts of Call, Helper, and Hash expressions:
{{method(arg1,arg2}} Call
{{helper arg1 arg2}} Helper
{{method( prop=hashValue )}} Hash
The value returned up by a KeyLookup depends on what the key looks like, and what expression type the KeyLookup is within.
For example, {{method(~./key)}}
will call method
with
a compute that looks up the value of key
only in the top of the scope.
The rules are as follows:
- call expression arguments
{{method(key)}}
- values are passed. - helper expression arguments
{{helper key}}
- computes are passed. - hash value in call expression
{{method(hash=key)}}
- values are set as property values. - hash value in helper expression
{{method hash=key}}
- computes are set as property values. - special operator
{{%index}}
- lookup values in a special context provided by some helpers. - compute operator
{{method(~key)}}
- pass a compute instead of a value. - at operator
{{method(@key}}
- pass a function instead of trying to read the value of the function. - current context
{{./key}}
- only lookup key at the top of the scope. - parent context
{{../key}}
- lookup the value in the parent context. - context
{{.}}
- return the current context/top of the scope.
Hash expressions
A Hash Expression specifies a property value on a object argument in a call expression and property value on the the hash object in a helper expression’s helperOptions argument.
For example, in a call expression:
<!-- Template -->
{{methodA(prop=key)}}
{{methodB(propX=key propY='literal', propZ=5)}}
/* Data */
{
methodA: function(arg) {},
methodB: function(arg1, arg2) {},
key: compute("value")
}
methodA
will be called with{prop: "value"}
asarg
.methodB
will be called with{propX: "value", propY: 'literal'}
asarg1
and{propZ: 5}
asarg2
In a helper expression:
<!-- Template -->
{{methodA prop=key}}
{{methodB(propX=key propY='literal' propZ=5)}}
/* Data */
{
methodA: function(options) {},
methodB: function(options) {},
key: compute("value")
}
methodA
will be called with{prop: compute("value")}
asoptions.hash
.methodB
will be called with{propX: "value", propY: 'literal', propZ: 5}
asoptions.hash
.
Call expressions
A Call Expression calls a function looked up in the scope followed by the helpers scope. It looks like:
<!-- Template -->
<h1>{{pluralize(type, ages.length)}}</h1>
/* Data */
{
pluralize: function(type, count){
return type+(count === 1 ? "" : "s")
},
ages: new List([22,32,42]),
type: "age"
}
<!-- Result -->
<h1>Ages</h1>
Call expression arguments are comma (,) separated. If a Hash expression is an argument, an object with the hash properties and values will be passed. For example:
<!-- Template -->
<h1>{{pluralize(word=type count=ages.length)}}</h1>
/* Data */
{
pluralize: function(options){
return options.word+(options.count === 1 ? "" : "s")
},
ages: new List([22,32,42]),
type: "age"
}
<!-- Result -->
<h1>Ages</h1>
Helper expressions
A Helper Expression calls a function looked up in the helpers scope followed by the scope. It looks like:
<!-- Template -->
<h1>{{pluralize type ages.length}}</h1>
/* Data */
{
pluralize: function(type, count){
return "data-pluralize"
},
todos: new List([22,32,42]),
type: "age"
}
/* Helpers */
{
pluralize: function(type, count){
return type+(count() === 1 ? "" : "s")
}
}
<!-- Result -->
<h1>Ages</h1>
Helper expression arguments that are observable are passed a compute. This is in contrast to Call expressions that get passed the value.
Helper expression arguments are space separated. If a Hash expression is an argument, the hash properties and values will be added to the helper options object. For example:
<!-- Template -->
<h1>{{pluralize word=type count=ages.length}}</h1>
/* Data */
{
todos: new List([22,32,42]),
type: "age"
}
/* Helpers */
{
pluralize: function(helperOptions){
return helperOptions.hash.type+(helperOptions.hash.count() === 1 ? "" : "s")
}
}
<!-- Result -->
<h1>Ages</h1>
Bracket expressions
A Bracket Expression can be used to look up a dynamic property in the scope. This looks like:
<!-- Template -->
<h1>{{[key]}}</h1>
/* Data */
{
key: "name",
name: "Kevin"
}
<!-- Result -->
<h1>Kevin</h1>
This can be useful for looking up values using keys containing non-alphabetic characters:
<!-- Template -->
<h1>{{["person:name"]}}</h1>
/* Data */
{
"person:name": "Kevin"
}
<!-- Result -->
<h1>Kevin</h1>
Bracket expressions can also be used to look up a value in the result of another expression:
<!-- Template -->
{{getPerson()[key]}}
/* Data */
{
key: "name",
getPerson: function() {
return {
name: "Kevin"
};
}
}
<!-- Result -->
<h1>Kevin</h1>