Notes from the ember.js guide

Published on

Walking through the Ember guide it takes about two hours to get up-and-running with an ember app.

It helps that the project is hosted on github. I did find a few updates that had to be made and some great resources along the way. Let’s get to it.

First, there were two jQuery plugins to install; showdown.js and moment.js.

Moment is a library for “parsing, validating, manipulating, and formatting dates. Basically, it shows “time ago” information made popular by sites like Twitter and Facebook.

Showdown takes markdown and converts it to HTML. Markdown is used by applications like Github and it’s non-official blogging software Jekyll to rapidly create HTML documents.

Overall though, the ember team put together a brilliant little demo that just scratches the surface of how much can be accomplished. To go from zero to a single-page web app (SPA) in under two hours is pretty amazing, even more so when you consider that the entire app is running on less than 70 lines of “functional” JavaScript code.

So here are a few things I took notes on while following along.

Resources are ‘pages’

And setting up a resource is pretty straightforward.

    
  App.Router.map(function(){
    this.resource('about');
    this.resource('posts', function(){
      // this nested resource inside a function for 'posts' created a child route
      this.resource('post', { path: ':post_id' });
    });

Printing your pages isn’t crazy town either.

<ul class="nav">
   <li>{{#link-to 'posts'}}Posts{{/link-to}}</li>
   <li>{{#link-to 'about'}}About{{/link-to}}</li>
</ul>

The trick here is on line 3 where we open a new function and nest one of our “resources” within the posts page. The nested post is now available to use with the {{outlet}} ember syntax in an {{#each}} call back.

Check out the loop below. It’s using the {{outlet}} ember syntax to retrieve the nested post object from the App.Router.map function.

 <script type="text/x-handlebars" id="posts">
    <div class="container-fluid">
      <div class="row-fluid">
        <div class="span3">
          <table class='table'>
            <thead>
              <tr><th>Recent Posts</th></tr>
            </thead>
            {{#each}}
            <tr><td>
              {{#link-to 'post' this}}
  <!-- passing 'this' refers back to #each -->
                {{title}} <small class='muted'>by {{author.name}}</small>
              {{/link-to}}
           </td></tr>
            {{/each}}
          </table>
        </div>
        <div class="span9">
          {{outlet}}
        </div>
      </div>
    </div>
  </script>

So there we have it, links and pages, all working together with nested posts within our post page. Good so far. For now, I’m using static Javascript objects in my apps.js file but you could also use a live feed of json objects from an open API like tumblr or SoundCloud or whatever.

Here’s an example of an object or ‘data’ that’s populating the posts.

    //Objects
    var posts = [{
    id: '1',
    title: "Rails is Omakase",
    author: { name: "d2h" },
    date: new Date('11-11-2013'),
    excerpt: "There are lots of à la carte software environments in this world. Places where in order to eat, you must first carefully look over the menu of options to order exactly what you want.",
    body: "I want this for my ORM, I want that for my template language, and let's finish it off with this routing library. Of course, you're going to have to know what you want, and you'll rarely have your horizon expanded if you always order the same thing, but there it is. It's a very popular way of consuming software.\n\nRails is not that. Rails is omakase."
  }

The next part is the model. A relatively brief syntax that can be modified with jQuery to pull JSON or XML data from a live API. The example below creates a subclass of the route object and assigns data to it, in this case, our posts object.

  // Route Model Hook - creates a subclass of the route object
    App.PostsRoute = Ember.Route.extend({
        model:function() {
            return posts;
        }
  });

Of course there are several other pieces we didn’t get into here, including:

  • How to pass in a dynamic post ID to the URL
  • The controller we created to edit our app
  • Setting up the controller for the live editing functionality
  • Building in helper functions for handlebars, including the showdown.js and moment.js objects

The handlebars.js library is really great, too, definitely valuable to help create modular blobs of markup for those of us who enjoy semantics. I can definitely see how flexible and efficient it would be to maintain different modules if you were scaling an application.

I should point out that I found an error in the demo when adding the showdown.js plug-in. For whatever reason, the object for the showdown library wasn’t being found. I checked the library itself to make sure I had the right namespace and it turns out that you need to call .converter() prior to registering the helper. In other words, you can grab the code that worked for me below.

   // Important to make sure to escape any returned HTMl to avoid XSS attacks http://goo.gl/gGdV
   var showdown = new Showdown.converter();
      Ember.Handlebars.registerBoundHelper('markdown', function(input) {
      return new Ember.Handlebars.SafeString(showdown.makeHtml(input));
   });

Check out the Demo

nettuts+ also has a nice ember.js write up.

Smashing Magazine weighs in, too ember.js