Ember at Embedly: Introduction to Ember Development

Every time I see Ember on Hacker News it’s being trashed, like MongoDB trashed. It sucks for an open source project when the herd mentality kicks in and it becomes cool to hate. Sadly, I’m not one of the cool kids.

Ember is excellent. We use it extensively here at Embedly for our developer dashboard. While none of us here are JavaScript experts, Ember has made us incredibly productive.

We are going to do a series of posts on Ember at Embedly. Mostly tips and tricks that have made us successful. These are not aimed at the pro, but the amateur.

A lot goes in to baking a production-quality website, and Ember adds to that. As a result, there is a lot of boilerplate when it comes to setting up the development environment. Rest assured that once you fight through the boilerplate, you’ll be able to iterate at an impressive rate.

Okay, so you have a new awesome idea of what you are going to build, how do you get started?

Yeoman/Grunt

Grunt is the Javascript Task Runner. It makes the set up of common tools like jshint, compass, uglify and development servers dead simple. We use it in almost every project now and it has made development a whole lot easier.

Yeoman is a thin wrapper around Grunt that really just builds out a directory structure and a few files. One member of your team will use it once and never think about it again.

So, let’s get started.

$ mkdir demo
$ cd demo
$ npm install -g yo grunt-cli bower

At the time of writing, the ember generator for yeoman is hosed, so you can do what you wish with that information. We can just use the default webapp generator.

$ yo webapp
$ npm install & bower install

This will build a pretty simple directory structure.

  app /
    index.html
    scripts/
      main.js
    styles/
      main.css
  Gruntfile.js
  package.json
  test /

Yeoman sets up the project so it can immediately be used. Run grunt’s server to launch your new web app.

$ grunt server

Tada, a browser will open to http://localhost:9000/ and show a nice little Allo message.

Getting Ember

Bower is Twitter’s package management tool for the Web. Let’s get Ember installed using bower.

$ bower install ember

Bower will handle getting all the right dependencies and install them in a components directory. You will then need to add Ember and Handlebars to your index.html file.

$ vim app/index.html

You can put the following lines near the bottom but above main.js:

<script src="components/handlebars/handlebars.js"></script>
<script src="components/ember/ember.js"></script>

Grunt will live reload your browser. You now have all the dependencies for a simple Ember app. You can prove it by opening up the console and running Em.

To recap, that was about 5 commands to get Ember completely ready to go:

$ npm install -g yo grunt-cli bower
$ yo webapp
$ npm install && bower install
$ bower install ember
$ vim app/index.html

If you complain about how hard Ember is to set up you are using the wrong tools.

Templates

Here on out is optional, but will probably save you some headaches later down the road. We will set up grunt-ember-templates, an Application and the Router.

The grunt-ember-templates module pre-compiles all your templates on the fly and adds them to Em.Templates, which is where Ember keeps your templates so it can match them to your views, based on naming convention. More on this later.

$ npm install grunt-ember-templates --save-dev
# Create the templates directory.
$ mkdir app/templates
$ touch app/templates/index.handlebars

We are going to have to update the Gruntfile to run ember_templates

Grunt is configured by a Gruntfile.js, which uses JSON to define a bunch of different actions that Grunt can perform for you. This is where we’ll hook up grunt-ember-templates to Grunt.

$ vim Gruntfile.js

In the Gruntfile, you are going to load the task before, I generally put it before the grunt.initConfig

grunt.loadNpmTasks('grunt-ember-templates');

Inside the grunt.initConfig you will need to set up the compile task to point at all the templates.

ember_templates: {
  compile: {
    options: {
      templateName: function(sourceFile) {
        return sourceFile.replace(/app\/templates\//, '');
      }
    },
    files: {
      "<%= yeoman.app %>/scripts/templates.js": ["<%= yeoman.app %>/templates/**/*.handlebars"]
    }
  }
},

Next tell the watch command to look for changes in the templates directory to make the live reload work correctly:

watch {
  ...
  ember_templates: {
      files: '<%= yeoman.app %>/templates/**/*.handlebars',
      tasks: ['ember_templates']
  },
  ...
}

Lastly, add ember_templates to the server task, you are looking for this line:

grunt.registerTask('server', function (target) {
    ...
    grunt.task.run([
        ...
        'compass:server',
        'ember_templates', // Add this line.
        'livereload-start',
        ...
    ]);
});

Once you restart grunt server, you can take a gander at the app/scripts/templates.js file in scripts. It should look something like this:

Ember.TEMPLATES["index"] = Ember.Handlebars.template
...

Add that script to the index.html file to make sure the browser loads it.

<script src="scripts/templates.js"></script>

That was kind of a detour, you don’t really need to set up ember_templates, you can use inline script tags or Em.Handlebars.compile, but this method offers a nice separation of HTML and javascript. For a quick reference you can see the completed Gruntfile here.

Application

The last step here will be to set up a simple App and Router to take advantage of our setup.

You can add the main.js to the end of index.html and delete whatever is in that file.

<script src="scripts/main.js"></script>

Next set up a rootElement for Ember to use, this will make sure that Ember puts the html where you want it to. Replace the div with the class container with:

<div id="app"></div>

Next add a simple Application to main.js:

App = Em.Application.create({
  rootElement: $('#app'),
});

You can then edit index.handlebars with a simple h1

$ echo "<h1>My App</h1>" > app/templates/index.handlebars

When grunt reloads the server, your browser will have My App as the header. There is a little magic going on here. Ember is creating a Router for you and by default creates and Application Route and an Index Route. This is why just adding an index.handlebars works.

The Router is dead simple to set up as well. In main.js add

App.Router.map(function(){
  this.route('about');
});

And then create the about template

$ echo "<h1>About</h1>" > app/templates/about.handlebars

If you navigate to /#/about, boom, you are now in the About route. You can also link to the about page from index by adding:

{{#linkTo "about"}}About{{/linkTo}}

This all works based on naming conventions. You can create an AboutController, AboutRoute and AboutView, but Ember will take care of that for these simple routes. More on that later.

Recap

Setting up Ember is a lot of boiler plate code, and there are some really good tools out there that do it for you. Nothing I have described above is earth shattering, but it should get you set up for your next Ember project.

I put the complete demo on Github for reference you can find it at github.com/screeley/ember-demo-environment.

For our next post in the Ember series, we will go into Ember basics; Views, Routing and Outlets. Stay tuned.

- Sean

Discuss on Hacker News

Posted 1 year ago by screeley
Embed This
  1. kano89 reblogged this from embedly
  2. embedly posted this