Announcing Symfony Ember.js Edition

We’ve spent a lot of time getting the configuration right for setting up Ember.js and EmberData to work with a Symfony backend. So we have decided to release a working example of getting this right:

Symfony Ember.js Edition

Background

The Ilios project is investigating a migration to Ember.js. Because we have a lot of PHP experience and a lot of PHP code, it makes sense to serve the content using Symfony. We chose Ember.js because of its convention over configuration approach and wanted to make as few customizations as possible.

EmberData provides a clean way to represent your data models in JavaScript and bind them to templates and controllers. It also has built-in REST functionality for keeping those models up to date on the server.

Specific Fixes

Compiling Handlebars templates

Ember expects compiled Handlebars templates to be in the JavaScript Ember.TEMPLATES object instead of Handlebars.template. That’s fine if you put all of your templates in index.html like they do in most examples. In that case, Ember does the compilation itself.

However we wanted separate templates and routers in different files. This required pre-compiling the templates for Ember. Thankfully there is a Node.js application for doing this already called ember-precompile.

It is even supported in the latest version of Assetic. However AsseticBundle hasn’t been updated in a while, so we had to mess with the Composer definition to get this working. The Assetic compiler will fail silently if you don’t have ember-precompile installed in /usr/bin/ember-precompile. Hopefully a fix for that will be available soon.

Testing the API

We want test coverage for our API, but actually getting the right input proved to be a bit complicated. There is a demo controller test and a base test in the AcmeApiBundle in this distribution. You can use it as a starting point to make writing other tests easier.

JS Dependencies

We use Bower to install all of our dependencies, include them in the layout, and manage their version without checking the code into our repo.

None of this would have been possible without: