Apr 13, 2015
Table of contents:
Last week we looked at setting up an Ember application as part of an existing Laravel repository.
Ember is a front-end framework that makes building interactive client-side applications much easier than rolling your own Javascript.
One of the core components of Ember is it’s templating engine. In today’s tutorial we will explore the Ember templating engine to learn more about how Ember works.
If you read last week’s post , you will remember that we peaked into the application.hbs
file.
<h2 id="title">Welcome to Ember.js</h2>
{{outlet}}
We also added a index.hbs
file and then we fired up ember serve
to see that our file had automatically been injected into the page.
The application.hbs
is your main application template file and so it is where you will put your header and footer stuff.
The {{outlet}}
tag is where the actual contents of the page will be injected.
You can have multiple named outlets to designate multiple areas of the page, but we’ll cross that bridge when we come to it.
If you’ve ever done any kind of Javascript view templating in the past, you’ve probably already heard of Handlebars.js.
Handlebars.js is a logicless templating language that make it really easy to draw a line between the view and the data.
Ember builds upon Handlebars.js by extending the language to include some of the really amazing features of Ember.
Properties in Handlars.js are wrapped using the {{property}}
syntax and all view properties will be automatically kept up-to-date by Ember as data across your application changes.
The following is a run down of the most common Handlebars helpers you will find yourself using when writing Ember application views.
A very common requirement of a view is to only show a section based upon some condition. To achieve this we can use the if
helper:
{{#if user}}
<p>Hello {{user.username}}!</p>
{{/if}}
If the value you pass to the if
helper evaluates to true
, the section inside the block will be rendered.
If you want to render an alternative in the case of a false
value, you can also include an {{else}}
block:
{{#if user}}
<p>Hello {{user.username}}!</p>
{{else}}
<p>Hello guest!</p>
{{/if}}
If you want to only display a section of the view if the condition evaluates as false
you can use the unless
helper:
{{#unless user}}
<p>You need to sign in</p>
{{/unless}}
Another common requirement is when you have a list of items that you need to display on a page. To iterate through the list and display each item, you can use the each
helper:
{{#each post in posts }}
<h2>{{post.title}}</h2>
<p>{{post.excerpt}}</p>
{{/each}}
You can also {{else}}
block that will be displayed if there are no items in the list:
{{#each post in posts }}
<h2>{{post.title}}</h2>
<p>{{post.excerpt}}</p>
{{else}}
<p>There are no posts to display.</p>
{{/each}}
All web applications will require links between the various pages of the user interface. It’s usually a good practice to avoid hard coding links into your views as it becomes a bit of a nightmare to update them when your routes inevitable change.
Ember provides the link-to
helper to deal with this functionality:
{{#link-to 'index'}}Home{{/link-to}}
The would render to the following HTML:
<a href="/">Home</a>
You can also pass in model objects that will automatically be used as part of dynamic routes:
{{#each post in posts}}
<h2>{{#link-to 'posts.view' post}}{{post.title}}{{/link-to}}</h2>
<p>{{post.excerpt}}</p>
{{/each}}
This would render as:
<h2><a href="/posts/1">Post title</a></h2>
<p>Post except</p>
<h2><a href="/posts/2">Post title</a></h2>
<p>Post except</p>
<h2><a href="/posts/3">Post title</a></h2>
<p>Post except</p>
One of the really nice little touches from Ember is that a class of active
will automatically be injected into the link that represents the current page.
This means it’s very easy to highlight where there the user is in the navigation, for example.
One of the big benefits of using a front-end framework like Ember is that it make it really easy to add interactivity to your application.
One way of doing this is by adding the {{action}}
helper to an element in the view:
<button {{action 'comments'}}>View Comments</button>
When the user clicks this button, the named event comments
will be sent to your application. This will trigger the method on the Controller that is associated with this View:
App.PostController = Ember.ObjectController.extend({
actions: {
comments: function () {
// Load and display comments
},
},
});
One of the best showcases of Ember’s functionality is the binding between input elements. When the user types into an input element you can very easily display it as part of the View.
{{input name="email" placeholder="Enter your email"}}
If you want to dispatch an action on a specific event, you can do so using the on
property:
{{input name="search" action="search" on="key-press"}}
A really great use case of this functionality is to show automatic previews of what your user is typing in.
Sometimes it useful to bind attributes from your Controller into the view. For example, you might have the following in your template:
<input name="email" required={{isRequired}}>
If the isRequired
attribute is true
, this element will be rendered as:
<input name="email" required>
However, if the isRequired
attribute is false
, the element will be rendered as:
<input name="email">
You can also bind class
attributes to elements like this:
<fieldset class="{{highlight}}">
</fieldset>
If the highlight
attribute is set as warning
, the template above would render as:
<fieldset class="warning">
</fieldset>
If you want to add a class
attribute based on a boolean
value, you can write the following:
<fieldset class="{{required}}">
</fieldset>
If required
property is set as true
, the template above would be rendered as:
<fieldset class="required">
</fieldset>
However, if the required
property is set as false
, the template would be rendered as:
<fieldset>
</fieldset>
Using a templating language like Handlebars.js is a great way to keep your Views clean. Inevitably there is always going to be some “logic” in your View, but by using a templating system you will keep your Views clean and tidy.
Handlebars.js is baked right into Ember and so the two aspects of your client-side application will really work well together. We will explore some more of these integrations as we continue our deep dive into Ember.
This is a series of posts on building an entire Open Source application called Cribbb. All of the tutorials will be free to web, and all of the code is available on GitHub.