2
votes

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.

2
any ideas? anyone? even stupid ones? :)andrusieczko
One struggles to find the right metaphor. Steaming pile? House of cards? Bowl of spaghetti? Whichever it is, things should not be this hard, meaning this is not a well-designed framework.user663031

2 Answers

2
votes

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'
            }
        }
    },
0
votes

So the whole solution is as follows:

module.exports = {
  debug: {
    src: "app/templates/**/*.{hbs,hjs,handlebars}",
    dest: "tmp/result/assets/templates.js"
  },
  dist: {
    src: "<%= emberTemplates.debug.src %>",
    dest: "<%= emberTemplates.debug.dest %>"
  },
  options: {
    templateCompilerPath: 'vendor/ember/ember-template-compiler.js',
    handlebarsPath: 'vendor/handlebars/handlebars.js',
    templateNamespace: 'HTMLBars',
    templateBasePath: "app/templates"
  }
};

where all my templates reside in app/templates/ directory.

I'm still using:

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

in index.html.

Maybe somebody will find it useful ;)