Magic Tag Types
Rendering behavior is controlled with magic tags that look like {{}}
. There
are two main forms of magic tags:
- Insertion tags - insert their value into the result like
{{expression}}
and{{{expression}}}
. - Section tags - optional render a sub-section like
{{#expression}} ... {{/expression}}
.
Let’s see the general behavior of each tag type:
Insertion Tags
Insertion tags render a value into result.
{{expression}}
Inserts the escaped value of expression
into the result. This is the most common tag.
<!-- Template -->
<div>{{name}}</div>
{ name: "<b>Justin</b>" }
<!-- Result -->
<div><b>Justin</b></div>
{{{expression}}}
Inserts the unescaped value of expression
into the result.
<!-- Template -->
<div>{{{name}}}</div>
{ name: "<b>Justin</b>" }
<!-- Result -->
<div><b>Justin</b></div>
This also works for rendering can-component instances:
import Component from "can-component";
import stache from "can-stache";
const MyGreeting = Component.extend({
tag: "my-greeting",
view: "<p>Hello {{subject}}</p>",
ViewModel: {
subject: "string"
}
});
const myGreetingInstance = new MyGreeting({
viewModel: {
subject: "friend"
}
});
const template = stache("<div>{{{componentInstance}}}</div>");
const fragment = template({
componentInstance: myGreetingInstance
});
fragment; //-> <div><my-greeting><p>Hello friend</p></my-greeting></div>
{{>key}}
Renders another template with the same context as the current context.
const template = stache( "<h1>{{>title}}</h1>" );
const frag = template(
{ message: "Hello" },
{
partials: { title: stache( "<blink>{{message}}</blink>" ) }
} );
frag; //-> <h1><blink>Hello</blink></h1>
Other ways to load and reference partials are discussed here.
{{!expression}}
Ignores the magic tag.
<!-- Template -->
<h1>{{!message}}</h1>
{ message: "<blink>Hello</blink>"; };
<!-- Result -->
<h1></h1>
Section Tags
Section tags are passed a subsection and an optional inverse subsection. They optionally render the subsections and insert them into the result.
{{#expression}} ... {{/expression}}
Renders the subsection or inverse subsection depending on the value of expression.
If expression
is truthy, renders the subsection:
<!-- Template -->
<h1>{{#shown}}Hello{{/shown}}</h1>
{ shown: true; };
<!-- Result -->
<h1>Hello</h1>
The subsection is rendered with the expression
value as the top of the scope:
<!-- Template -->
<h1>{{#person}}Hello {{first}} {{person.last}}{{/person}}</h1>
{ person: { first: "Alexis", last: "Abril" } }
<!-- Result -->
<h1>Hello Alexis Abril</h1>
If expression
is falsey, renders the inverse subsection if present:
<!-- Template -->
<h1>{{#shown}}Hello{{else}}Goodbye{{/shown}}</h1>
{ shown: false }
<!-- Result -->
<h1>Goodbye</h1>
If expression
is array-like and its length
is greater than 0, the subsection
is rendered with each item in the array as the top of the scope:
<!-- Template -->
<p>{{#items}}{{.}} {{/items}}</p>
{ items: [ 2, 4, 8, 16 ] }
<!-- Result -->
<p>2 4 8 16 </p>
If expression
is array-like and its length
is 0, the inverse subsection
is rendered:
<!-- Template -->
<p>{{#items}}{{.}} {{else}}No items{{/items}}</p>
{ items: [] }
<!-- Result -->
<p>No items</p>
{{^expression}} ... {{/expression}}
The inverse section does the opposite of the normal {{#expression}} tag. That is, it renders the subsection when {{#expression}} would render the inverse subsection and it renders the inverse subsection when {{#expression}} would render the subsection.
<!-- Template -->
<h1>{{^shown}}Hello{{/shown}}</h1>
{ shown: false }
<!-- Result -->
<h1>Hello</h1>