can.stache

  • function
can/view/stache 2.1
 

Logic-less Handlebar and Mustache templates with live binding.

can.stache(template)

Processes the template and returns a renderer function that renders the template with data and local helpers.

Parameters

  1. template {String}

    The text of a mustache template.

Returns

{renderer(data, helpers)}

A renderer function that returns a live document fragment that can be inserted in the page.

Use

Mustache and Handlebar templates are compatible with can.stache.

Stache templates looks similar to normal HTML except they contain keys for inserting data into the template and sections to enumerate and/or filter the enclosed template blocks.

For example, the following renders a welcome header for a user and displays the number of messages.

Stache Template

<script id="template" type="text/stache">
    <h1>Welcome {{user}}!</h1>
    <p>You have {{messages}} messages.</p>
</script>

JavaScript

var data = new can.Map({
    user: 'Tina Fey',
    messages: 0
});

var template = can.view("#template", data)
document.body.appendChild(template);

HTML Result

<h1>Welcome Tina Fey!</h1>
<p>You have 0 messages.</p>

To update the html using live-binding, change an observable value:

data.attr('message', 5)

This updates this paragraph in the HTML Result to:

<p>You have 5 messages.</p>

can.stache provides significantly more functionality such as:

Differences from can.mustache

can.stache is largely compatable with can.mustache. There are three main differences:

Passing values in the scope to can.Components

A can.mustache template passes values from the scope to a can.Component by specifying the key of the value in the attribute directly. For example:

can.Component.extend({
  tag: "my-tag",
  template: "<h1>{{greeting}}</h1>"
});
var template = can.mustache("<my-tag greeting='message'></my-tag>");

var frag = template({
  message: "Hi"
});

frag //-> <my-tag greeting='message'><h1>Hi</h1></my-tag>

With stache, you wrap the key with {}. For example:

can.Component.extend({
  tag: "my-tag",
  template: "<h1>{{greeting}}</h1>"
});
var template = can.stache("<my-tag greeting='{message}'></my-tag>");

var frag = template({
  message: "Hi"
});
 
frag //-> <my-tag greeting='{message}'><h1>Hi</h1></my-tag>

If the key was not wrapped, the template would render:

frag //-> <my-tag greeting='message'><h1>message</h1></my-tag>

Because the attribute value would be passed as the value of gretting.

Section renderers return documentFragments

A Mustache section renderer called like options.fn() or options.inverse() would always return a String. For example, the following would wrap the .fn section in an <h1> tag:

can.mustache.registerHelper("wrapH1", function(options.fn()){
   return "<h1>"+options.fn()+"</h1>";
});

var template = can.mustache("{{#wrapH1}}Hi There!{{/#wrapH1}}");
template() //-> <h1>Hi There</h1>

can.staches section renderers return documentFragments when sections are not contained within an html element. This means the result of the previous helper would be:

<h1>[object DocumentFragment]</h1>

Instead, helper functions should manipulate the document fragment into the desired response. With jQuery, this can be done like:

can.stache.registerHelper("wrapH1", function(options.fn()){
   return $("<h1>").append( options.fn() );
});

var template = can.stache("{{#wrapH1}}Hi There!{{/#wrapH1}}");
template() //-> <h1>Hi There</h1>

Element callbacks are no longer supported

can.mustache supported element callbacks like {{(el) -> CODE}}. These are not supported in can.stache. Instead, create a helper that returns a function or register a custom attribute.

can.stache.registerHelper("elementCallback", function(){
  return function(el){
    CODE
  }
});

can.view.tag("element-callback", function(el){
  CODE
})

Tags

{{key}}

Insert the value of the key into the output of the template.

{{{key}}}

Behaves just like {{key}} and {{helper}} but does not escape the result.

{{&key}}

The `{{&key}}` tag is an alias for {{{key}}}, behaving just like {{key}} and {{helper}} but does not escape the result.

{{#key}}BLOCK{{/key}}

Render blocks of text one or more times, depending on the value of the key in the current context.

{{/key}}

Ends a {{#key}} or [can.stache.tags.sectionHelper {{#helper}}] block.

{{^key}}BLOCK{{/key}}

Render blocks of text if the value of the key is falsey.

{{>key}}

Render another template within the current template.

{{!key}}

The comment tag operates similarly to a `` tag in HTML.