Search code examples
ember.jshandlebars.js

Ember 1.10+grunt+EAK: "Could not find <template_name> template or view" after migration from 1.9.1


I'm using Ember App Kit with grunt and I'm trying to switch to Ember 1.10 and can't get HTMLBars working :/

TL;DR

After migration, I've got my HTMLBars templates lodaded in Ember.TEMPLATES but they're not visible either by Ember nor in App.__container.lookup.cache.

Details

The steps I did:

  • updated ember and ember-data
  • updated package.json ("grunt-ember-templates": "0.5.0")
  • updated my Gruntfile.js (grunt.loadNpmTasks('grunt-ember-templates') added a task emberTemplates)
  • passed the options to emberTemplates:

    {
      debug: [],
      options: {
        templateCompilerPath: 'vendor/ember/ember-template-compiler.js',
        handlebarsPath: 'vendor/handlebars/handlebars.js',
        templateNamespace: 'HTMLBars'
      },
      'public/assets/templates.js': [
        'app/templates/**/*.hbs'
      ],
    };
    
  • removed handlebars.js from index.html and replaced ember.js with ember.debug.js

Now, I've got my public/assets/templates.js file generated in a proper way, I had several compilation errors coming from ember-template-compiler, so this part, I assume, is working fine.

Lastly, in the app, I can see all my templates loaded in Ember.TEMPLATES variable but unfortunately, they're not accessible from App.__container__.lookup.cache or App.__container__.lookup('template:<template_name>').

The way I'm trying to render the template that throws an error is (and it's working with Ember 1.9):

export default AuthRoute.extend({

  renderTemplate: function() {
    this.render();
    this.render('user-details', {
      into: 'base',
      outlet: 'profile',
      controller: 'user-details'
    });
  }
});

What am I missing? Any help would be appreciated.

Bonus question: what is debug field in emberTemplates configuration? If I don't define it, it raises an error (Required config property "emberTemplates.debug" missing.) while compiling. Could that be a possible reason?

Bonus question 2: where should templates.js file go? The intuition tells me /tmp but then, even Ember.TEMPLATES is an empty object...

EDIT [SOLUTION]:

I missed templateBasePath: "app/templates" line in the emberTemplates options. Because of that, Ember.TEMPLATES object was sth similar to this:

{
  "app/templates/base.hbs": {},
  "app/templates/components/component.hbs": {}
}

instead of:

{
  "base.hbs": {},
  "components/component.hbs": {}
}

which is the format that Ember resolver (ember-application/system/resolver) in the resolveTemplate method expects.


Solution

  • EDIT: using grunt-ember-templates and this Gruntfile task, I got it working:

    emberTemplates: {
        options: {
            precompile: true,
            templateBasePath: "templates",
            handlebarsPath: "node_modules/handlebars/dist/handlebars.js",
            templateCompilerPath: "bower_components/ember/ember-template-compiler.js"
        },
        "dist/js/templates.js": ["templates/**/*.hbs"]
    }       
    

    Differences seem to be precompile: true and point the handlebarsPath to the dependency in node_modules. Also the templateBasePath makes the ids like application instead of templates/application. Or in your case app/templates/application.

    To answer your Bonus question 2, put templates.js after you load ember.js but before your app.js. Mine script includes look like this:

    <script type="text/javascript" src="/bower_components/ember/ember.debug.js"></script>
    <script type="text/javascript" src="/bower_components/ember/ember-template-compiler.js"></script>
    <script type="text/javascript" src="/js/templates.js"></script>
    <script type="text/javascript" src="/js/app.js"></script>
    

    ====================================

    EDIT: Ignore this newbness...

    It seems like the grunt-ember-templates task is outdated, or its dependencies are outdated. Remove it. I was able to hack together this solution:

    Use grunt-contrib-concat instead. The money is with the process option.

        concat: {
            dist: {
                // other concat tasks...
            },
            templates: {
                options: {
                    banner: '',
                    process: function(src, filepath) {
                        var name = filepath.replace('app/templates/','').replace('.hbs','');
                        var Map = {
                            10: "n",
                            13: "r",
                            39: "'",
                            34: '"',
                            92: "\\"
                        };
                        src = '"' + src.replace(/[\n\r\"\\]/g, function(m) {
                            return "\\" + Map[m.charCodeAt(0)]
                        }) + '"';                       
    
                        return 'Ember.TEMPLATES["'+name+'"] = Ember.HTMLBars.template(Ember.HTMLBars.compile('+src+'));\n';
                    }
                },
                files: {
                    'public/assets/templates.js': 'app/templates/**/*.hbs'
                }
            }
        },