Ember.Handlebars.helpers Class packages/ember-handlebars-compiler/lib/main.js:145


Show:

_triageMustache

(property, options) String private

'_triageMustache' is used internally select between a binding, helper, or component for the given context. Until this point, it would be hard to determine if the mustache is a property reference or a regular helper reference. This triage helper resolves that.

This would not be typically invoked by directly.

Parameters:

property String
Property/helperID to triage
options Object
hash of template/rendering options

Returns:

String
HTML string

action

(actionName, context, options)

The {{action}} helper provides a useful shortcut for registering an HTML element within a template for a single DOM event and forwarding that interaction to the template's controller or specified target option. If the controller does not implement the specified action, the event is sent to the current route, and it bubbles up the route hierarchy from there. For more advanced event handling see Ember.Component

Use

Given the following application Handlebars template on the page handlebars <div {{action 'anActionName'}}> click me </div> And application code javascript App.ApplicationController = Ember.Controller.extend({ actions: { anActionName: function() { } } }); Will result in the following rendered HTML html <div class="ember-view"> <div data-ember-action="1"> click me </div> </div> Clicking "click me" will trigger the anActionName action of the App.ApplicationController. In this case, no additional parameters will be passed. If you provide additional parameters to the helper: handlebars <button {{action 'edit' post}}>Edit</button> Those parameters will be passed along as arguments to the JavaScript function implementing the action.

Event Propagation

Events triggered through the action helper will automatically have .preventDefault() called on them. You do not need to do so in your event handlers. If you need to allow event propagation (to handle file inputs for example) you can supply the preventDefault=false option to the {{action}} helper: handlebars <div {{action "sayHello" preventDefault=false}}> <input type="file" /> <input type="checkbox" /> </div> To disable bubbling, pass bubbles=false to the helper: handlebars <button {{action 'edit' post bubbles=false}}>Edit</button> If you need the default handler to trigger you should either register your own event handler, or use event methods on your view class. See Ember.View 'Responding to Browser Events' for more information.

Specifying DOM event type

By default the {{action}} helper registers for DOM click events. You can supply an on option to the helper to specify a different DOM event name: handlebars <div {{action "anActionName" on="doubleClick"}}> click me </div> See Ember.View 'Responding to Browser Events' for a list of acceptable DOM event names.

Specifying whitelisted modifier keys

By default the {{action}} helper will ignore click event with pressed modifier keys. You can supply an allowedKeys option to specify which keys should not be ignored. handlebars <div {{action "anActionName" allowedKeys="alt"}}> click me </div> This way the {{action}} will fire when clicking with the alt key pressed down. Alternatively, supply "any" to the allowedKeys option to accept any combination of modifier keys. handlebars <div {{action "anActionName" allowedKeys="any"}}> click me with any key pressed </div>

Specifying a Target

There are several possible target objects for {{action}} helpers: In a typical Ember application, where templates are managed through use of the {{outlet}} helper, actions will bubble to the current controller, then to the current route, and then up the route hierarchy. Alternatively, a target option can be provided to the helper to change which object will receive the method call. This option must be a path to an object, accessible in the current context: handlebars {{! the application template }} <div {{action "anActionName" target=view}}> click me </div> javascript App.ApplicationView = Ember.View.extend({ actions: { anActionName: function(){} } });

Additional Parameters

You may specify additional parameters to the {{action}} helper. These parameters are passed along as the arguments to the JavaScript function implementing the action. handlebars {{#each person in people}} <div {{action "edit" person}}> click me </div> {{/each}} Clicking "click me" will trigger the edit method on the current controller with the value of person as a parameter.

Parameters:

actionName String
context [Object]
options Hash

bind

(property, fn) String private

bind can be used to display a value, then update that value if it changes. For example, if you wanted to print the title property of content:

1
{{bind "content.title"}}

This will return the title property as a string, then create a new observer at the specified path. If it changes, it will update the value in DOM. Note that if you need to support IE7 and IE8 you must modify the model objects properties using Ember.get() and Ember.set() for this to work as it relies on Ember's KVO system. For all other browsers this will be handled for you automatically.

Parameters:

property String
Property to bind
fn Function
Context to provide for rendering

Returns:

String
HTML string

bind-attr

(options) String

bind-attr allows you to create a binding between DOM element attributes and Ember objects. For example:

1
<img {{bind-attr src="imageUrl" alt="imageTitle"}}>

The above handlebars template will fill the <img>'s src attribute with the value of the property referenced with "imageUrl" and its alt attribute with the value of the property referenced with "imageTitle".

If the rendering context of this template is the following object:

1
2
3
4
{
  imageUrl: 'http://lolcats.info/haz-a-funny',
  imageTitle: 'A humorous image of a cat'
}

The resulting HTML output will be:

1
<img src="http://lolcats.info/haz-a-funny" alt="A humorous image of a cat">

bind-attr cannot redeclare existing DOM element attributes. The use of src in the following bind-attr example will be ignored and the hard coded value of src="/failwhale.gif" will take precedence:

1
<img src="/failwhale.gif" {{bind-attr src="imageUrl" alt="imageTitle"}}>

bind-attr and the class attribute

bind-attr supports a special syntax for handling a number of cases unique to the class DOM element attribute. The class attribute combines multiple discrete values into a single attribute as a space-delimited list of strings. Each string can be:

  • a string return value of an object's property.
  • a boolean return value of an object's property
  • a hard-coded value

A string return value works identically to other uses of bind-attr. The return value of the property will become the value of the attribute. For example, the following view and template:

1
2
3
4
5
  AView = View.extend({
    someProperty: function() {
      return "aValue";
    }.property()
  })
1
<img {{bind-attr class="view.someProperty}}>

Result in the following rendered output:

1
<img class="aValue">

A boolean return value will insert a specified class name if the property returns true and remove the class name if the property returns false.

A class name is provided via the syntax somePropertyName:class-name-if-true.

1
2
3
AView = View.extend({
  someBool: true
})
1
<img {{bind-attr class="view.someBool:class-name-if-true"}}>

Result in the following rendered output:

1
<img class="class-name-if-true">

An additional section of the binding can be provided if you want to replace the existing class instead of removing it when the boolean value changes:

1
<img {{bind-attr class="view.someBool:class-name-if-true:class-name-if-false"}}>

A hard-coded value can be used by prepending : to the desired class name: :class-name-to-always-apply.

1
<img {{bind-attr class=":class-name-to-always-apply"}}>

Results in the following rendered output:

1
<img class="class-name-to-always-apply">

All three strategies - string return value, boolean return value, and hard-coded value – can be combined in a single declaration:

1
<img {{bind-attr class=":class-name-to-always-apply view.someBool:class-name-if-true view.someProperty"}}>

Parameters:

options Hash

Returns:

String
HTML string

bindAttr

(context, options) String deprecated

See bind-attr

Parameters:

context Function
options Hash

Returns:

String
HTML string

boundIf

(property, fn) String private

Use the boundIf helper to create a conditional that re-evaluates whenever the truthiness of the bound value changes.

1
2
3
{{#boundIf "content.shouldDisplayTitle"}}
  {{content.title}}
{{/boundIf}}

Parameters:

property String
Property to bind
fn Function
Context to provide for rendering

Returns:

String
HTML string

collection

(path, options) String deprecated

Use {{each}} helper instead.

{{collection}} is a Ember.Handlebars helper for adding instances of Ember.CollectionView to a template. See Ember.CollectionView for additional information on how a CollectionView functions.

{{collection}}'s primary use is as a block helper with a contentBinding option pointing towards an Ember.Array-compatible object. An Ember.View instance will be created for each item in its content property. Each view will have its own content property set to the appropriate item in the collection.

The provided block will be applied as the template for each item's view.

Given an empty <body> the following template:

1
2
3
4
{{! application.hbs }}
{{#collection content=model}}
  Hi {{view.content.name}}
{{/collection}}

And the following application code

1
2
3
4
5
6
App = Ember.Application.create();
App.ApplicationRoute = Ember.Route.extend({
  model: function(){
    return [{name: 'Yehuda'},{name: 'Tom'},{name: 'Peter'}];
  }
});

The following HTML will result:

1
2
3
4
5
<div class="ember-view">
  <div class="ember-view">Hi Yehuda</div>
  <div class="ember-view">Hi Tom</div>
  <div class="ember-view">Hi Peter</div>
</div>

Non-block version of collection

If you provide an itemViewClass option that has its own template you may omit the block.

The following template:

1
2
{{! application.hbs }}
{{collection content=model itemViewClass="an-item"}}

And application code

1
2
3
4
5
6
7
8
9
10
App = Ember.Application.create();
App.ApplicationRoute = Ember.Route.extend({
  model: function(){
    return [{name: 'Yehuda'},{name: 'Tom'},{name: 'Peter'}];
  }
});

App.AnItemView = Ember.View.extend({
  template: Ember.Handlebars.compile("Greetings {{view.content.name}}")
});

Will result in the HTML structure below

1
2
3
4
5
<div class="ember-view">
  <div class="ember-view">Greetings Yehuda</div>
  <div class="ember-view">Greetings Tom</div>
  <div class="ember-view">Greetings Peter</div>
</div>

Specifying a CollectionView subclass

By default the {{collection}} helper will create an instance of Ember.CollectionView. You can supply a Ember.CollectionView subclass to the helper by passing it as the first argument:

1
2
3
{{#collection "my-custom-collection" content=model}}
  Hi {{view.content.name}}
{{/collection}}

This example would look for the class App.MyCustomCollection.

Forwarded item.*-named Options

As with the {{view}}, helper options passed to the {{collection}} will be set on the resulting Ember.CollectionView as properties. Additionally, options prefixed with item will be applied to the views rendered for each item (note the camelcasing):

1
2
3
4
5
{{#collection content=model
              itemTagName="p"
              itemClassNames="greeting"}}
  Howdy {{view.content.name}}
{{/collection}}

Will result in the following HTML structure:

1
2
3
4
5
<div class="ember-view">
  <p class="ember-view greeting">Howdy Yehuda</p>
  <p class="ember-view greeting">Howdy Tom</p>
  <p class="ember-view greeting">Howdy Peter</p>
</div>

Parameters:

path String
options Hash

Returns:

String
HTML string

debugger

(property)

Execute the debugger statement in the current context.

1
{{debugger}}

Before invoking the debugger statement, there are a few helpful variables defined in the body of this helper that you can inspect while debugging that describe how and where this helper was invoked:

  • templateContext: this is most likely a controller from which this template looks up / displays properties
  • typeOfTemplateContext: a string description of what the templateContext is

For example, if you're wondering why a value {{foo}} isn't rendering as expected within a template, you could place a {{debugger}} statement, and when the debugger; breakpoint is hit, you can inspect templateContext, determine if it's the object you expect, and/or evaluate expressions in the console to perform property lookups on the templateContext:

1
  > templateContext.get('foo') // -> "<value of {{foo}}>"

Parameters:

property String

each

(name, path, options)

The {{#each}} helper loops over elements in a collection. It is an extension of the base Handlebars {{#each}} helper.

The default behavior of {{#each}} is to yield its inner block once for every item in an array. Each yield will provide the item as the context of the block.

1
var developers = [{name: 'Yehuda'},{name: 'Tom'}, {name: 'Paul'}];
1
2
3
4
{{#each developers}}
  {{name}}
  {{! `this` is each developer }}
{{/each}}

{{#each}} supports an alternative syntax with element naming. This preserves context of the yielded block:

1
2
3
4
{{#each person in developers}}
  {{person.name}}
  {{! `this` is whatever it was outside the #each }}
{{/each}}

The same rules apply to arrays of primitives, but the items may need to be references with {{this}}.

1
var developerNames = ['Yehuda', 'Tom', 'Paul']
1
2
3
{{#each developerNames}}
  {{this}}
{{/each}}

{{else}} condition

{{#each}} can have a matching {{else}}. The contents of this block will render if the collection is empty.

1
2
3
4
5
{{#each person in developers}}
  {{person.name}}
{{else}}
  <p>Sorry, nobody is available for this task.</p>
{{/each}}

Specifying an alternative view for each item

itemViewClass can control which view will be used during the render of each item's template.

The following template:

1
2
3
4
5
<ul>
{{#each developers itemViewClass="person"}}
  {{name}}
{{/each}}
</ul>

Will use the following view for each item

1
2
3
App.PersonView = Ember.View.extend({
  tagName: 'li'
});

Resulting in HTML output that looks like the following:

1
2
3
4
5
<ul>
  <li class="ember-view">Yehuda</li>
  <li class="ember-view">Tom</li>
  <li class="ember-view">Paul</li>
</ul>

itemViewClass also enables a non-block form of {{each}}. The view must {{#crossLink "Ember.View/toc_templates"}}provide its own template{{/crossLink}}, and then the block should be dropped. An example that outputs the same HTML as the previous one:

1
2
3
4
App.PersonView = Ember.View.extend({
  tagName: 'li',
  template: '{{name}}'
});
1
2
3
<ul>
  {{each developers itemViewClass="person"}}
</ul>

Specifying an alternative view for no items (else)

The emptyViewClass option provides the same flexibility to the {{else}} case of the each helper.

1
2
3
4
App.NoPeopleView = Ember.View.extend({
  tagName: 'li',
  template: 'No person is available, sorry'
});
1
2
3
4
5
<ul>
{{#each developers emptyViewClass="no-people"}}
  <li>{{name}}</li>
{{/each}}
</ul>

Wrapping each item in a controller

Controllers in Ember manage state and decorate data. In many cases, providing a controller for each item in a list can be useful. Specifically, an {{#crossLink "Ember.ObjectController"}}Ember.ObjectController{{/crossLink}} should probably be used. Item controllers are passed the item they will present as a model property, and an object controller will proxy property lookups to model for us.

This allows state and decoration to be added to the controller while any other property lookups are delegated to the model. An example:

1
2
3
4
5
App.RecruitController = Ember.ObjectController.extend({
  isAvailableForHire: function() {
    return !this.get('isEmployed') && this.get('isSeekingWork');
  }.property('isEmployed', 'isSeekingWork')
})
1
2
3
{{#each person in developers itemController="recruit"}}
  {{person.name}} {{#if person.isAvailableForHire}}Hire me!{{/if}}
{{/each}}

(Experimental) Grouped Each

If a list's membership often changes, but properties of items in that group rarely change, a significant improvement in template rendering time can be achieved by using the experimental group helper.

1
2
3
4
5
{{#group}}
  {{#each people}}
    {{firstName}} {{lastName}}
  {{/each}}
{{/group}}

When the membership of people changes, or when any property changes, the entire {{#group}} block will be re-rendered.

An {{#each}} inside the {{#group}} helper can opt-out of the special group behavior by passing the groupedRows option. For example:

1
2
3
4
5
6
7
8
9
10
11
{{#group}}
  {{#each dealers}}
    {{! uses group's special behavior }}
    {{firstName}} {{lastName}}
  {{/each}}

  {{#each car in cars groupedRows=true}}
    {{! does not use group's special behavior }}
    {{car.make}} {{car.model}} {{car.color}}
  {{/each}}
{{/group}}

Any change to the dealers collection will cause the entire group to be re-rendered. Changes to the cars collection will be re-rendered individually, as they are with normal {{#each}} usage.

{{#group}} is implemented with an itemViewClass, so specifying an itemViewClass on an {{#each}} will also disable the special re-rendering behavior.

Parameters:

name [String]
name for item (used with `in`)
path [String]
path
options [Object]
Handlebars key/value pairs of options
itemViewClass [String]
a path to a view class used for each item
emptyViewClass [String]
a path to a view class used for each item
itemController [String]
name of a controller to be created for each item
groupedRows [Boolean]
enable normal item-by-item rendering when inside a `#group` helper

helperMissing

(path, options) private

Registers a helper in Handlebars that will be called if no property with the given name can be found on the current context object, and no helper with that name is registered.

This throws an exception with a more helpful error message so the user can track down where the problem is happening.

Parameters:

path String
options Hash

if

(context, options) String

See boundIf and unboundIf

Parameters:

context Function
options Hash

Returns:

String
HTML string

input

(options)

The {{input}} helper inserts an HTML <input> tag into the template, with a type value of either text or checkbox. If no type is provided, text will be the default value applied. The attributes of {{input}} match those of the native HTML tag as closely as possible for these two types.

Use as text field

An {{input}} with no type or a type of text will render an HTML text input. The following HTML attributes can be set via the helper:

readonlyrequiredautofocus
valueplaceholderdisabled
sizetabindexmaxlength
nameminmax
patternacceptautocomplete
autosaveformactionformenctype
formmethodformnovalidateformtarget
heightinputmodemultiple
stepwidthform
selectionDirectionspellcheck 

When set to a quoted string, these values will be directly applied to the HTML element. When left unquoted, these values will be bound to a property on the template's current rendering context (most typically a controller instance).

Unbound:

1
  {{input value="http://www.facebook.com"}}
1
  <input type="text" value="http://www.facebook.com"/>

Bound:

1
2
3
4
  App.ApplicationController = Ember.Controller.extend({
    firstName: "Stanley",
    entryNotAllowed: true
  });
1
  {{input type="text" value=firstName disabled=entryNotAllowed size="50"}}
1
  <input type="text" value="Stanley" disabled="disabled" size="50"/>

Actions

The helper can send multiple actions based on user events. The action property defines the action which is sent when the user presses the return key. handlebars {{input action="submit"}} The helper allows some user events to send actions.

  • enter
  • insert-newline
  • escape-press
  • focus-in
  • focus-out
  • key-press

For example, if you desire an action to be sent when the input is blurred, you only need to setup the action name to the event name property. handlebars {{input focus-in="alertMessage"}} See more about Text Support Actions

Extension

Internally, {{input type="text"}} creates an instance of Ember.TextField, passing arguments from the helper to Ember.TextField's create method. You can extend the capabilities of text inputs in your applications by reopening this class. For example, if you are building a Bootstrap project where data-* attributes are used, you can add one to the TextField's attributeBindings property:

1
2
3
  Ember.TextField.reopen({
    attributeBindings: ['data-error']
  });

Keep in mind when writing Ember.TextField subclasses that Ember.TextField itself extends Ember.Component, meaning that it does NOT inherit the controller of the parent view. See more about Ember components

Use as checkbox

An {{input}} with a type of checkbox will render an HTML checkbox input. The following HTML attributes can be set via the helper:

  • checked
  • disabled
  • tabindex
  • indeterminate
  • name
  • autofocus
  • form

When set to a quoted string, these values will be directly applied to the HTML element. When left unquoted, these values will be bound to a property on the template's current rendering context (most typically a controller instance).

Unbound:

1
  {{input type="checkbox" name="isAdmin"}}
1
  <input type="checkbox" name="isAdmin" />

Bound:

1
2
3
  App.ApplicationController = Ember.Controller.extend({
    isAdmin: true
  });
1
  {{input type="checkbox" checked=isAdmin }}
1
  <input type="checkbox" checked="checked" />

Extension

Internally, {{input type="checkbox"}} creates an instance of Ember.Checkbox, passing arguments from the helper to Ember.Checkbox's create method. You can extend the capablilties of checkbox inputs in your applications by reopening this class. For example, if you wanted to add a css class to all checkboxes in your application:

1
2
3
  Ember.Checkbox.reopen({
    classNames: ['my-app-checkbox']
  });

Parameters:

options Hash

link-to

(routeName, context, options) String

The {{link-to}} helper renders a link to the supplied routeName passing an optionally supplied model to the route as its model context of the route. The block for {{link-to}} becomes the innerHTML of the rendered element:

1
2
3
{{#link-to 'photoGallery'}}
  Great Hamster Photos
{{/link-to}}
1
2
3
<a href="/hamster-photos">
  Great Hamster Photos
</a>

Supplying a tagName

By default {{link-to}} renders an <a> element. This can be overridden for a single use of {{link-to}} by supplying a tagName option:

1
2
3
{{#link-to 'photoGallery' tagName="li"}}
  Great Hamster Photos
{{/link-to}}
1
2
3
<li>
  Great Hamster Photos
</li>

To override this option for your entire application, see "Overriding Application-wide Defaults".

By default {{link-to}} is enabled. any passed value to disabled helper property will disable the link-to helper.

static use: the disabled option:

1
2
3
{{#link-to 'photoGallery' disabled=true}}
  Great Hamster Photos
{{/link-to}}

dynamic use: the disabledWhen option:

1
2
3
{{#link-to 'photoGallery' disabledWhen=controller.someProperty}}
  Great Hamster Photos
{{/link-to}}

any passed value to disabled will disable it except undefined. to ensure that only true disable the link-to helper you can override the global behaviour of Ember.LinkView.

1
2
3
4
5
6
7
8
Ember.LinkView.reopen({
  disabled: Ember.computed(function(key, value) {
    if (value !== undefined) {
      this.set('_isDisabled', value === true);
    }
    return value === true ? get(this, 'disabledClass') : false;
  })
});

see "Overriding Application-wide Defaults" for more.

Handling href

{{link-to}} will use your application's Router to fill the element's href property with a url that matches the path to the supplied routeName for your routers's configured Location scheme, which defaults to Ember.HashLocation.

Handling current route

{{link-to}} will apply a CSS class name of 'active' when the application's current route matches the supplied routeName. For example, if the application's current route is 'photoGallery.recent' the following use of {{link-to}}:

1
2
3
{{#link-to 'photoGallery.recent'}}
  Great Hamster Photos from the last week
{{/link-to}}

will result in

1
2
3
<a href="/hamster-photos/this-week" class="active">
  Great Hamster Photos
</a>

The CSS class name used for active classes can be customized for a single use of {{link-to}} by passing an activeClass option:

1
2
3
{{#link-to 'photoGallery.recent' activeClass="current-url"}}
  Great Hamster Photos from the last week
{{/link-to}}
1
2
3
<a href="/hamster-photos/this-week" class="current-url">
  Great Hamster Photos
</a>

To override this option for your entire application, see "Overriding Application-wide Defaults".

Supplying a model

An optional model argument can be used for routes whose paths contain dynamic segments. This argument will become the model context of the linked route:

1
2
3
App.Router.map(function() {
  this.resource("photoGallery", {path: "hamster-photos/:photo_id"});
});
1
2
3
{{#link-to 'photoGallery' aPhoto}}
  {{aPhoto.title}}
{{/link-to}}
1
2
3
<a href="/hamster-photos/42">
  Tomster
</a>

Supplying multiple models

For deep-linking to route paths that contain multiple dynamic segments, multiple model arguments can be used. As the router transitions through the route path, each supplied model argument will become the context for the route with the dynamic segments:

1
2
3
4
5
App.Router.map(function() {
  this.resource("photoGallery", {path: "hamster-photos/:photo_id"}, function() {
    this.route("comment", {path: "comments/:comment_id"});
  });
});

This argument will become the model context of the linked route:

1
2
3
{{#link-to 'photoGallery.comment' aPhoto comment}}
  {{comment.body}}
{{/link-to}}
1
2
3
<a href="/hamster-photos/42/comment/718">
  A+++ would snuggle again.
</a>

Supplying an explicit dynamic segment value

If you don't have a model object available to pass to {{link-to}}, an optional string or integer argument can be passed for routes whose paths contain dynamic segments. This argument will become the value of the dynamic segment:

1
2
3
App.Router.map(function() {
  this.resource("photoGallery", {path: "hamster-photos/:photo_id"});
});
1
2
3
{{#link-to 'photoGallery' aPhotoId}}
  {{aPhoto.title}}
{{/link-to}}
1
2
3
<a href="/hamster-photos/42">
  Tomster
</a>

When transitioning into the linked route, the model hook will be triggered with parameters including this passed identifier.

Allowing Default Action

By default the {{link-to}} helper prevents the default browser action by calling preventDefault() as this sort of action bubbling is normally handled internally and we do not want to take the browser to a new URL (for example).

If you need to override this behavior specify preventDefault=false in your template:

1
2
3
{{#link-to 'photoGallery' aPhotoId preventDefault=false}}
  {{aPhotoId.title}}
{{/link-to}}

Overriding attributes

You can override any given property of the Ember.LinkView that is generated by the {{link-to}} helper by passing key/value pairs, like so:

1
2
3
{{#link-to  aPhoto tagName='li' title='Following this link will change your life' classNames='pic sweet'}}
  Uh-mazing!
{{/link-to}}

See Ember.LinkView for a complete list of overrideable properties. Be sure to also check out inherited properties of LinkView.

Overriding Application-wide Defaults

{{link-to}} creates an instance of Ember.LinkView for rendering. To override options for your entire application, reopen Ember.LinkView and supply the desired values:

1
2
3
4
Ember.LinkView.reopen({
  activeClass: "is-active",
  tagName: 'li'
})

It is also possible to override the default event in this manner:

1
2
3
Ember.LinkView.reopen({
  eventName: 'customEventName'
});

Parameters:

routeName String
context [Object]
options [Object]
Handlebars key/value pairs of options, you can override any property of Ember.LinkView

Returns:

String
HTML string

linkTo

(routeName, context) String deprecated

See link-to

Parameters:

routeName String
context [Object]

Returns:

String
HTML string

loc

(str)

Calls Ember.String.loc with the provided string.

This is a convenient way to localize text within a template:

1
2
3
Ember.STRINGS = {
  '_welcome_': 'Bonjour'
};
1
2
3
<div class='message'>
  {{loc '_welcome_'}}
</div>
1
2
3
<div class='message'>
  Bonjour
</div>

See Ember.String.loc for how to set up localized string references.

Parameters:

str String
The string to format

log

(property)

log allows you to output the value of variables in the current rendering context. log also accepts primitive types such as strings or numbers.

1
{{log "myVariable:" myVariable }}

Parameters:

property String

outlet

(property) String

The outlet helper is a placeholder that the router will fill in with the appropriate template based on the current state of the application.

1
{{outlet}}

By default, a template based on Ember's naming conventions will be rendered into the outlet (e.g. App.PostsRoute will render the posts template).

You can render a different template by using the render() method in the route's renderTemplate hook. The following will render the favoritePost template into the outlet.

1
2
3
4
5
App.PostsRoute = Ember.Route.extend({
  renderTemplate: function() {
    this.render('favoritePost');
  }
});

You can create custom named outlets for more control.

1
2
{{outlet 'favoritePost'}}
{{outlet 'posts'}}

Then you can define what template is rendered into each outlet in your route.

1
2
3
4
5
6
App.PostsRoute = Ember.Route.extend({
  renderTemplate: function() {
    this.render('favoritePost', { outlet: 'favoritePost' });
    this.render('posts', { outlet: 'posts' });
  }
});

You can specify the view that the outlet uses to contain and manage the templates rendered into it.

1
{{outlet view='sectionContainer'}}
1
2
3
4
App.SectionContainer = Ember.ContainerView.extend({
  tagName: 'section',
  classNames: ['special']
});

Parameters:

property String
the property on the controller that holds the view for this outlet

Returns:

String
HTML string

partial

(partialName)

The partial helper renders another template without changing the template context:

1
2
{{foo}}
{{partial "nav"}}

The above example template will render a template named "nav", which has the same context as the parent template it's rendered into, so if the "nav" template also referenced {{foo}}, it would print the same thing as the {{foo}} in the above example.

If a "_nav" template isn't found, the partial helper will fall back to a template named "nav".

Bound template names

The parameter supplied to partial can also be a path to a property containing a template name, e.g.:

1
{{partial someTemplateName}}

The above example will look up the value of someTemplateName on the template context (e.g. a controller) and use that value as the name of the template to render. If the resolved value is falsy, nothing will be rendered. If someTemplateName changes, the partial will be re-rendered using the new template name.

Setting the partial's context with with

The partial helper can be used in conjunction with the with helper to set a context that will be used by the partial:

1
2
3
{{#with currentUser}}
  {{partial "user_info"}}
{{/with}}

Parameters:

partialName String
the name of the template to render minus the leading underscore

query-params

(hash) String

Parameters:

hash Object
takes a hash of query parameters

Returns:

String
HTML string

render

(name, contextString, options) String

Calling {{render}} from within a template will insert another template that matches the provided name. The inserted template will access its properties on its own controller (rather than the controller of the parent template).

If a view class with the same name exists, the view class also will be used.

Note: A given controller may only be used once in your app in this manner. A singleton instance of the controller will be created for you.

Example:

1
2
3
App.NavigationController = Ember.Controller.extend({
  who: "world"
});
1
2
<!-- navigation.hbs -->
Hello, {{who}}.
1
2
3
<!-- application.hbs -->
<h1>My great app</h1>
{{render "navigation"}}
1
2
3
4
<h1>My great app</h1>
<div class='ember-view'>
  Hello, world.
</div>

Optionally you may provide a second argument: a property path that will be bound to the model property of the controller.

If a model property path is specified, then a new instance of the controller will be created and {{render}} can be used multiple times with the same name.

For example if you had this author template.

1
2
3
4
<div class="author">
Written by {{firstName}} {{lastName}}.
Total Posts: {{postCount}}
</div>

You could render it inside the post template using the render helper.

1
2
3
4
5
<div class="post">
<h1>{{title}}</h1>
<div>{{body}}</div>
{{render "author" author}}
</div>

Parameters:

name String
contextString Object?
options Hash

Returns:

String
HTML string

resolveHelper

(container, name) Handlebars Helper private

Used to lookup/resolve handlebars helpers. The lookup order is:

  • Look for a registered helper
  • If a dash exists in the name:
    • Look for a helper registed in the container
    • Use Ember.ComponentLookup to find an Ember.Component that resolves to the given name

Parameters:

container Container
name String
the name of the helper to lookup

Returns:

Handlebars Helper

template

(templateName) deprecated

Parameters:

templateName String
the template to render

textarea

(options)

{{textarea}} inserts a new instance of <textarea> tag into the template. The attributes of {{textarea}} match those of the native HTML tags as closely as possible.

The following HTML attributes can be set:

  • value
  • name
  • rows
  • cols
  • placeholder
  • disabled
  • maxlength
  • tabindex
  • selectionEnd
  • selectionStart
  • selectionDirection
  • wrap
  • readonly
  • autofocus
  • form
  • spellcheck
  • required

When set to a quoted string, these value will be directly applied to the HTML element. When left unquoted, these values will be bound to a property on the template's current rendering context (most typically a controller instance).

Unbound:

1
{{textarea value="Lots of static text that ISN'T bound"}}

Would result in the following HTML:

1
2
3
<textarea class="ember-text-area">
  Lots of static text that ISN'T bound
</textarea>

Bound:

In the following example, the writtenWords property on App.ApplicationController will be updated live as the user types 'Lots of text that IS bound' into the text area of their browser's window.

1
2
3
App.ApplicationController = Ember.Controller.extend({
  writtenWords: "Lots of text that IS bound"
});
1
{{textarea value=writtenWords}}

Would result in the following HTML:

1
2
3
<textarea class="ember-text-area">
  Lots of text that IS bound
</textarea>

If you wanted a one way binding between the text area and a div tag somewhere else on your screen, you could use Ember.computed.oneWay:

1
2
3
4
App.ApplicationController = Ember.Controller.extend({
  writtenWords: "Lots of text that IS bound",
  outputWrittenWords: Ember.computed.oneWay("writtenWords")
});
1
2
3
4
5
{{textarea value=writtenWords}}

<div>
  {{outputWrittenWords}}
</div>

Would result in the following HTML:

1
2
3
4
5
6
7
8
9
<textarea class="ember-text-area">
  Lots of text that IS bound
</textarea>

<-- the following div will be updated in real time as you type -->

<div>
  Lots of text that IS bound
</div>

Finally, this example really shows the power and ease of Ember when two properties are bound to eachother via Ember.computed.alias. Type into either text area box and they'll both stay in sync. Note that Ember.computed.alias costs more in terms of performance, so only use it when your really binding in both directions:

1
2
3
4
App.ApplicationController = Ember.Controller.extend({
  writtenWords: "Lots of text that IS bound",
  twoWayWrittenWords: Ember.computed.alias("writtenWords")
});
1
2
{{textarea value=writtenWords}}
{{textarea value=twoWayWrittenWords}}
1
2
3
4
5
6
7
8
9
<textarea id="ember1" class="ember-text-area">
  Lots of text that IS bound
</textarea>

<-- both updated in real time -->

<textarea id="ember2" class="ember-text-area">
  Lots of text that IS bound
</textarea>

Actions

The helper can send multiple actions based on user events.

The action property defines the action which is send when the user presses the return key.

1
{{input action="submit"}}

The helper allows some user events to send actions.

  • enter
  • insert-newline
  • escape-press
  • focus-in
  • focus-out
  • key-press

For example, if you desire an action to be sent when the input is blurred, you only need to setup the action name to the event name property.

1
{{textarea focus-in="alertMessage"}}

See more about Text Support Actions

Extension

Internally, {{textarea}} creates an instance of Ember.TextArea, passing arguments from the helper to Ember.TextArea's create method. You can extend the capabilities of text areas in your application by reopening this class. For example, if you are building a Bootstrap project where data-* attributes are used, you can globally add support for a data-* attribute on all {{textarea}}s' in your app by reopening Ember.TextArea or Ember.TextSupport and adding it to the attributeBindings concatenated property:

1
2
3
Ember.TextArea.reopen({
  attributeBindings: ['data-error']
});

Keep in mind when writing Ember.TextArea subclasses that Ember.TextArea itself extends Ember.Component, meaning that it does NOT inherit the controller of the parent view.

See more about Ember components

Parameters:

options Hash

unbound

(property) String

unbound allows you to output a property without binding. Important: The output will not be updated if the property changes. Use with caution.

1
<div>{{unbound somePropertyThatDoesntChange}}</div>

unbound can also be used in conjunction with a bound helper to render it in its unbound form:

1
<div>{{unbound helperName somePropertyThatDoesntChange}}</div>

Parameters:

property String

Returns:

String
HTML string

unboundIf

(property, fn) String private
Defined in packages/ember-handlebars/lib/helpers/binding.js:377
Available since 1.4.0

Parameters:

property String
Property to bind
fn Function
Context to provide for rendering

Returns:

String
HTML string

unless

(context, options) String

Parameters:

context Function
options Hash

Returns:

String
HTML string

view

(path, options) String

{{view}} inserts a new instance of an Ember.View into a template passing its options to the Ember.View's create method and using the supplied block as the view's own template.

An empty <body> and the following template:

1
2
3
4
A span:
{{#view tagName="span"}}
  hello.
{{/view}}

Will result in HTML structure:

1
2
3
4
5
6
7
8
9
10
11
12
<body>
  <!-- Note: the handlebars template script
       also results in a rendered Ember.View
       which is the outer <div> here -->

  <div class="ember-view">
    A span:
    <span id="ember1" class="ember-view">
      Hello.
    </span>
  </div>
</body>

parentView setting

The parentView property of the new Ember.View instance created through {{view}} will be set to the Ember.View instance of the template where {{view}} was called.

1
2
3
4
5
aView = Ember.View.create({
  template: Ember.Handlebars.compile("{{#view}} my parent: {{parentView.elementId}} {{/view}}")
});

aView.appendTo('body');

Will result in HTML structure:

1
2
3
4
5
<div id="ember1" class="ember-view">
  <div id="ember2" class="ember-view">
    my parent: ember1
  </div>
</div>

Setting CSS id and class attributes

The HTML id attribute can be set on the {{view}}'s resulting element with the id option. This option will not be passed to Ember.View.create.

1
2
3
{{#view tagName="span" id="a-custom-id"}}
  hello.
{{/view}}

Results in the following HTML structure:

1
2
3
4
5
<div class="ember-view">
  <span id="a-custom-id" class="ember-view">
    hello.
  </span>
</div>

The HTML class attribute can be set on the {{view}}'s resulting element with the class or classNameBindings options. The class option will directly set the CSS class attribute and will not be passed to Ember.View.create. classNameBindings will be passed to create and use Ember.View's class name binding functionality:

1
2
3
{{#view tagName="span" class="a-custom-class"}}
  hello.
{{/view}}

Results in the following HTML structure:

1
2
3
4
5
<div class="ember-view">
  <span id="ember2" class="ember-view a-custom-class">
    hello.
  </span>
</div>

Supplying a different view class

{{view}} can take an optional first argument before its supplied options to specify a path to a custom view class.

1
2
3
{{#view "custom"}}{{! will look up App.CustomView }}
  hello.
{{/view}}

The first argument can also be a relative path accessible from the current context.

1
2
3
4
5
6
7
8
9
MyApp = Ember.Application.create({});
MyApp.OuterView = Ember.View.extend({
  innerViewClass: Ember.View.extend({
    classNames: ['a-custom-view-class-as-property']
  }),
  template: Ember.Handlebars.compile('{{#view view.innerViewClass}} hi {{/view}}')
});

MyApp.OuterView.create().appendTo('body');

Will result in the following HTML:

1
2
3
4
5
<div id="ember1" class="ember-view">
  <div id="ember2" class="ember-view a-custom-view-class-as-property">
    hi
  </div>
</div>

Blockless use

If you supply a custom Ember.View subclass that specifies its own template or provide a templateName option to {{view}} it can be used without supplying a block. Attempts to use both a templateName option and supply a block will throw an error.

1
2
3
4
var App = Ember.Application.create();
App.WithTemplateDefinedView = Ember.View.extend({
  templateName: 'defined-template'
});
1
2
{{! application.hbs }}
{{view 'with-template-defined'}}
1
2
{{! defined-template.hbs }}
Some content for the defined template view.

viewName property

You can supply a viewName option to {{view}}. The Ember.View instance will be referenced as a property of its parent view by this name.

1
2
3
4
5
6
aView = Ember.View.create({
  template: Ember.Handlebars.compile('{{#view viewName="aChildByName"}} hi {{/view}}')
});

aView.appendTo('body');
aView.get('aChildByName') // the instance of Ember.View created by {{view}} helper

Parameters:

path String
options Hash

Returns:

String
HTML string

with

(context, options) String

Use the {{with}} helper when you want to scope context. Take the following code as an example:

1
2
3
4
5
6
7
8
<h5>{{user.name}}</h5>

<div class="role">
  <h6>{{user.role.label}}</h6>
  <span class="role-id">{{user.role.id}}</span>

  <p class="role-desc">{{user.role.description}}</p>
</div>

{{with}} can be our best friend in these cases, instead of writing user.role.* over and over, we use {{#with user.role}}. Now the context within the {{#with}} .. {{/with}} block is user.role so you can do the following:

1
2
3
4
5
6
7
8
9
10
<h5>{{user.name}}</h5>

<div class="role">
  {{#with user.role}}
    <h6>{{label}}</h6>
    <span class="role-id">{{id}}</span>

    <p class="role-desc">{{description}}</p>
  {{/with}}
</div>

as operator

This operator aliases the scope to a new name. It's helpful for semantic clarity and to retain default scope or to reference from another {{with}} block.

1
2
3
4
5
6
7
8
9
10
// posts might not be
{{#with user.posts as blogPosts}}
  <div class="notice">
    There are {{blogPosts.length}} blog posts written by {{user.name}}.
  </div>

  {{#each post in blogPosts}}
    <li>{{post.title}}</li>
  {{/each}}
{{/with}}

Without the as operator, it would be impossible to reference user.name in the example above.

NOTE: The alias should not reuse a name from the bound property path. For example: {{#with foo.bar as foo}} is not supported because it attempts to alias using the first part of the property path, foo. Instead, use {{#with foo.bar as baz}}.

controller option

Adding controller='something' instructs the {{with}} helper to create and use an instance of the specified controller with the new context as its content.

This is very similar to using an itemController option with the {{each}} helper.

1
2
3
{{#with users.posts controller='userBlogPosts'}}
  {{!- The current context is wrapped in our controller instance }}
{{/with}}

In the above example, the template provided to the {{with}} block is now wrapped in the userBlogPost controller, which provides a very elegant way to decorate the context with custom functions/properties.

Parameters:

context Function
options Hash

Returns:

String
HTML string

yield

(options) String

{{yield}} denotes an area of a template that will be rendered inside of another template. It has two main uses:

Use with layout

When used in a Handlebars template that is assigned to an Ember.View instance's layout property Ember will render the layout template first, inserting the view's own rendered output at the {{yield}} location.

An empty <body> and the following application code:

1
2
3
4
5
6
7
8
AView = Ember.View.extend({
  classNames: ['a-view-with-layout'],
  layout: Ember.Handlebars.compile('<div class="wrapper">{{yield}}</div>'),
  template: Ember.Handlebars.compile('<span>I am wrapped</span>')
});

aView = AView.create();
aView.appendTo('body');

Will result in the following HTML output:

1
2
3
4
5
6
7
<body>
  <div class='ember-view a-view-with-layout'>
    <div class="wrapper">
      <span>I am wrapped</span>
    </div>
  </div>
</body>

The yield helper cannot be used outside of a template assigned to an Ember.View's layout property and will throw an error if attempted.

1
2
3
4
5
6
7
8
9
10
11
BView = Ember.View.extend({
  classNames: ['a-view-with-layout'],
  template: Ember.Handlebars.compile('{{yield}}')
});

bView = BView.create();
bView.appendTo('body');

// throws
// Uncaught Error: assertion failed:
// You called yield in a template that was not a layout

Use with Ember.Component

When designing components {{yield}} is used to denote where, inside the component's template, an optional block passed to the component should render:

1
2
3
4
<!-- application.hbs -->
{{#labeled-textfield value=someProperty}}
  First name:
{{/labeled-textfield}}
1
2
3
4
<!-- components/labeled-textfield.hbs -->
<label>
  {{yield}} {{input value=value}}
</label>

Result:

1
2
3
<label>
  First name: <input type="text" />
</label>

Parameters:

options Hash

Returns:

String
HTML string