Templates

The interface of your app is based on powerful templates. We utilize a framework called Handlebars.js which allows the use of logic using data from your app, and a number of helpers we've prebuilt for you. If you're not familiar with Handlebars, do give their documentation a quick read, but we'll be covering a lot of it here.

File Structure

Within your app's .zip file, all your templates should be contained under the /templates directory. The optional layout.hdbs file is special; more on this below.

You can add more templates to your /templates directory, but they must be .hdbs file types. We talk about how to call those other templates below.

layout.hdbs

You can think of layout.hdbs as the template for your template files. Yes, that sounds a little confusing, so let's dive into an example.

Below is a standard layout.hdbs:

<header>
  <span class="logo"/>
  <h3>Bookmarks</h3>
</header>

<section data-main />

You can see it has a <header> section, which you may choose to include or not. The most important part to note here is <section data-main />.

The data-main section

This is where the real magic happens. Previously we noted that you can create any number of other template files in your /templates directory. You can dynamically load any of those templates into the <section data-main />, so essentially layout.hdbs is really just your header and footer template.

The image below shows how we're using layout.hdbs as that basic header/footer template, then embedding other named templates within layout.hdbs itself:

Template switching

In order to display a different template within <section data-main>, as illustrated in the image above, all we have to do is switch "states."

In our example app, under the /templates directory, you'll find a template called list.hdbs. The name of the template file is important, because in our app we will use the name of the template file to switch to it.

renderBookmarks: function(bookmarks) {
  this.bookmarks = bookmarks;
  this.switchTo('list', {
    bookmarks:            this.bookmarks,
    ticketIsBookmarkable: this.ticketIsBookmarkable()
  });
}

this.switchTo is used to change the contents of <section data-main /> with the template we name, which is where this.switchTo('list') comes in.

In our example we pass in data we want to use in list.hdbs. Let's take a look at that next. If you'd like to learn more about States, see Reference: Template

defaultState

If your app declares an defaultState property, it will switch to that state on initialization.

Data in Templates

Because templates support Handlebars syntax, you can easily display data or even use data to decide what to display.

Let's get back to our example

this.switchTo('list', {
  bookmarks:            this.bookmarks,
  ticketIsBookmarkable: this.ticketIsBookmarkable()
});

When calling this.switchTo, we also pass in some data we want to use: bookmarks and ticketIsBookmarkable. In the lists.hdbs these are used in two different ways:

{{#bookmarks}}
  <li data-bookmark-id="{{id}}">
    <a href="#/bookmarks/{{id}}/destroy" class="destroy" rel="nofollow" title="{{t "delete_bookmark"}}">
      <i class='icon-remove-circle'></i>
    </a>
    <a href="#/tickets/{{ticket.nice_id}}">{{ticket.subject}}</a>
  </li>
{{/bookmarks}}

The above takes the bookmarks data we passed in (which in this case is a JSON array) and iterates over it. You can use the data contained within the JSON using the named key -- {{ticket.nice_id}} for example. To learn more about iterating on data in templates, see Handlebars.js: Block Expression

The bookmarks data doesn't have to be used in Block Expressions; you could simply use it in an if-statement or unless clauses. For example:

{{#unless bookmarks.length}}
  <p>None</p>
{{/unless}}

Which says, "Unless the length of the bookmarks JSON array is nonzero, display the contents of this {{#unless}} block". Learn more about If, Unless, Each and With at Handlebars.js: Block Helpers

Finally, we can also display the value of a key inside the bookmarks JSON array:

{{ticket.subject}}

See Handlebars.js: Paths for more.

Other Helpers

As well as full support of Handlebars, we also have a number of other helpers which can be used to access Settings Data, Internationalized Strings, and Assets. See Reference: Template for more.

Next Step: Uploading →