Ember structure setup with Pods


#1

A while back on the ember blog, it was mentioned that the ember team was looking at doing a pod folder structure instead of the current ember structure. With that in mind, we started testing out a way to organize ember into pods, and have come up with a solution we like the structure of. I wanted I would throw it out here for two reasons.

  1. Show as example incase anyone else would like to use a pod structure.
  2. See if anyone else is using the different ember structure than the default, and get feedback.

Our basic structure is as follows


Index
[] = folder
() named object

  • [app]
    • [(misc folders)]
    • store.js
    • router.js
    • (top level app files)
  • [components]
    • [(component name)]
  • [initializers]
  • [helpers]
  • [mixins]
  • [models]
  • [pods]
    • [(resource name)]
      • [(route name)]
      • [(route name)]
      • [(nested resource name)]
        • [(route name)]

Inside a pod we usually combine the route, controller, and view into one file since the controller takes up the bulk of the code, and the route and optional view are usually only a few lines of code.

If our resource only has one route, we don’t create an additional subfolder (as with email below). Campaigns resource does have more than one route, so we split index and edit routes into their own folders.

If we have a specific view or component for a route or resource, we put it in the route or resource directory. If we have a global component then we put in the components folder.

Our pods folder ends up something like:

  • pods
    • campaigns
      • index
        • index.hjs
        • index.route.js.coffee (this has to have route appended on to avoid rails compiling down to index.js from the template and index.js from the javascript.)
        • custom.component.js.coffee
      • edit
        • (You could also do something like, if you like separate files)
        • edit.hjs
        • edit.route.js.coffee
        • edit.controller.js.coffee
        • edit.view.js.coffee
    • emails
      • index.hjs
      • index.route.js.coffee

In the end, everything works as expected with rails. The only change we had to make to ember to support the pods directory structure, was to update the template resolver, which can be found here:

It’s been nice to have all related route or resource files grouped together to easily find and work with. It would be nice if something more official was found, but this is what we have for now.

Note: We are using rails and coffeescript for our setup. Others may have to change some of this depending on their setup.


Ember Design/Best Practices for Large Scale Projects
#2

So it looks like ember-cli enforces a pod structure that’s a little closer to what they documented in the “What’s coming in Ember in 2014” article. We went a different direction by naming the files with their resource/route so it’s easier to find via keyboard shortcut.

The ember-cli version would for your example would look more like this

pods/

pods/campaigns/

pods/campaigns/index/
pods/campaigns/index/template.hbs
pods/campaigns/index/route.js
pods/campaigns/index/controller.js
pods/campaigns/index/view.js

components/custom-component.js

pods/campaigns/edit/
pods/campaigns/edit/template.hbs
pods/campaigns/edit/route.js
pods/campaigns/edit/controller.js
pods/campaigns/edit/view.js

pods/emails/
pods/emails/template.hbs
pods/emails/route.js

Partials, however, it looks like you need to either put them in their own folder or prefix the file with template. This creates a lot of single file folders.

pods/emails/
pods/emails/template.hbs
pods/emails/route.js

pods/emails/seed/template.hbs

pods/emails/address/template.hbs

pods/emails/body/template.hbs

pods/emails/signature/template.hbs

You can alternatively prefix the files with template to achieve a similar result.

pods/emails/
pods/emails/template.hbs
pods/emails/template.seed.hbs
pods/emails/template.address.hbs
pods/emails/template.body.hbs
pods/emails/template.signature.hbs
pods/emails/route.js

I plan on continuing to use pods (it was a format that I promoted in other languages as well.) I’m trying to wrap my head around the ember-cli enforced structure since it’s different than all of my projects.


#3

I can’t understate the gains I’ve made by using a modified pod structure in my app. As it’s grown, having all files named the same had me constantly tripping over myself.

My naming may be a little long for some, but there’s no room for confusion as to what you’re looking at. I use folder structure for encapsulation/organization, and file naming for identification.

app/pods/post/post-route.js
app/pods/post/post-controller.js
app/pods/post/post-template.hbs
app/pods/post/comments/post-comments-route.js
app/pods/post/comments/post-comments-controller.js
app/pods/post/comments/post-comments-controller-template.hbs

Using a simple addition to moduleNameLookupPatterns, it was easy to resolve these. Unfortunately, on 0.0.40 it’s required to naming all templates template.*. Sigh.

@aaronbhansen I like the idea of putting the route and controller in the same file, I’ll think about that one. Much of the time all I’m doing is declaring inheritance and maybe a property or two and that makes for a lot of small files.


#4

Per suggestion by @rwblue, I was able to get my app running in 0.0.40 by overriding EmberApp.prototype._processedTemplatesTree below the ember-app require statement in Brocfile.js. Unfortunately there are no hooks so I’m redeclaring the entire function. Excerpt:

  var podTemplates = pickFiles(this.trees.app, {
    srcDir: '/',
//    files: ['**/template.*'],
    files: ['**/*.hbs'],
    destDir: this.name + '/',
    allowEmpty: true
  });

#5

Don’t think that’s the case. Kind of thought the same reading this comment, but that’s not what the author actually suggests.