UNPKG

can

Version:

MIT-licensed, client-side, JavaScript framework that makes building rich web applications easy.

286 lines (219 loc) 7.35 kB
@page can.stache.Helpers Helpers @parent can.stache.pages 4 # Helpers Helpers are functions that can be registered and called from within templates. While stache is intended to be logic-less, helpers enable the execution of logic from within a stache template. Stache includes a number of built-in helpers, but custom helpers can be registered as well. The majority of these built-in helpers have [can.stache.Basics basic tag] equivalents. ## Built-in Helpers The `[can.stache.tags.section {{#if key}}]` helper is used for **if** statements. The **if** helper is equivalent to using a `[can.stache.tags.section {{#key}}]` section. If they key passed to the helper is **truthy**, the section will be rendered. Template: {{#if friends}} I have friends! {{/if}} Data: { friends: true } Result: I have friends! When using the `[can.stache.helpers.if {{#if key}}]` helper, or any other helper for that matter, the special `[can.stache.helpers.else {{else}}] helper becomes available. `{{else}}` is equivalent to an [can.stache.helpers.inverse {{^key}}] inverse section (rendering **falsey** data), except that it only uses a single tag and exists inside a helper section. Template: <ul> {{#if friends}} </li>{{name}}</li> {{else}} <li>No friends.</li> {{/if}} </ul> Data: { friends: false } Result: <ul> <li>No friends.</li> </ul> The `[can.stache.helpers.unless {{#unless key}}]` helper is equivalent to using a `[can.stache.helpers.inverse {{^key}}]` inverse section. If they key passed to the helper is **falsey**, the section will be rendered. Template: {{#unless friends}} You don't have any friends! {{/unless}} Data: { friends: [] } Result: You don't have any friends! The `[can.stache.helpers.each {{#each key}}]` helper is equivalent to using a `[can.stache.tags.section {{#key}}]` section for iterating an array. In this case, the entire array will be rendered using the inner text item by item. Template: <ul> {{#each friends}} <li>{{name}}</li> {{/each}} </ul> Data: { friends: [ { name: "Austin" }, { name: "Justin" } ] } Result: <ul> <li>Austin</li> <li>Justin</li> </ul> The `[can.stache.helpers.with {{#with key}}]` helper is equivalent to using a `[can.stache.tags.section {{#key}}]` section for regular objects. The helper will change the current context so that all tags inside will look for keys on the local context first. Template: <h1>Hi {{name}}</h1> {{#with friend}} <p>You have a new friend: {{name}}</p> {{/with}} Data: { name: "Andy", friend: { name: "Justin" } } Result: <h1>Hi Austin</h1> <p>You have a new friend: Justin</p> When using the `[can.mustache.helpers.is {{#is key1 key2}}]` helper you can simply compare key1 and key2. If the result of comparsion is **truthy**, the section will be rendered. Template: <ul> {{#is name 'Alex'}} </li>Your name is {{name}}</li> {{else}} <li>Your name is not Alex!</li> {{/is}} </ul> Data: { name: 'John' } Result: <ul> <li>Your name is not Alex!</li> </ul> The `[can.stache.helpers.data {{data key}}]` helper is another special helper for data associations that will save the current context on the active DOM element with [can.data]. Template: <ul> <li id="personli" {{data 'person'}}>{{name}}</li> </ul> Data: { name: 'Austin' } The data can be retrieved later with: var nameObject = can.data(can.$('#personli'), 'person'); ## Registering Helpers You can register your own global helper with the `[can.stache.registerHelper registerHelper]` method, or a local helper (just accessible by the template being rendered) by passing in an object containing helper functions to [can.view]. Localization is a good example of a custom helper you might implement in your application. The below example takes a given key and returns the localized value using [jQuery Globalize](https://github.com/jquery/globalize). can.stache.registerHelper('l10n', function(str, options){ return Globalize != undefined ? Globalize.localize(str) : str; }); Or another way to do this: can.view("//path/to/template.stache", data, { l10n: function(str, options){ return Globalize != undefined ? Globalize.localize(str) : str; } }) In the template, invoke the helper by calling the helper name followed by any additional arguments. Template: <span>{{l10n 'mystring'}}</span> Result: <span>my string localized</span> __Helpers with can.Map attributes__ If a can.Map attribute is passed as an argument to a helper, it is converted to a can.compute getter/setter function. This is to allow creating 2-way binding type functionality between a can.Map attribute and a form element. For example in your template: <div>{{addPrefix name}}</div> Your helper would look like: var item = new can.Map({name: "Brian"}), frag = can.view("#template", item, { addPrefix: function(name){ return "Mr." + name() } }); Note we're calling `name()` in order to read its contents. __Multiple Arguments__ You can pass multiple arguments just by putting a space between that and the previous argument like so: {{helper 'cat' 'hat'}} can.stache.registerHelper('helper', function(arg1, arg2, options){ // arg1 -> 'cat' // arg2 -> 'hat' }); __Evaluating Helpers__ If you want to use a helper with a [can.stache.Sections section], you need to call `options.fn(context)` in your return statement. This will return a string with the resulting evaluated [can.stache.Sections section]. Similarly, you can call `options.inverse(context)` to evaluate the template between an `{{else}}` tag and the closing tag. For example, when a route matches the string passed to our routing helper it will show/hide the text. can.stache.registerHelper('routing', function(str, options){ if (can.route.attr('filter') === str) return options.fn(this); } }); {{#routing 'advanced'}} You have applied the advanced filter. {{/routing}} __Advanced Helpers__ Helpers can be passed normal objects, native objects like numbers and strings, as well as a hash object. The hash object will be an object literal containing all ending arguments using the `key=value` syntax. The hash object will be provided to the helper as `options.hash`. Additionally, when using [can.stache.Sections section] with the helper, you can set a custom context by passing the object instead of `this`. can.stache.registerHelper('exercise', function(group, action, num, options){ if (group && group.length > 0 && action && num > 0) { return options.fn({ group: group, action: action, where: options.hash.where, when: options.hash.when, num: num }); } else { return options.inverse(this); } }); {{#exercise pets 'walked' 3 where='around the block' when=time}} Along with the {{#group}}{{.}}, {{/group}} we {{action}} {{where}} {{num}} times {{when}}. {{else}} We were lazy today. {{/exercise}} { pets: ['cat', 'dog', 'parrot'], time: 'this morning' } This would output: Along with the cat, dog, parrot, we walked around the block 3 times this morning. Whereas an empty data object would output: We were lazy today.