Sam Saffron
Sam Saffron

Reputation: 131112

How do you add the "each in" to work in handlebars

Ember is migrating to a non-context switching #each helper. For a compatibility piece I need to do the same from raw handlebars.

However the trivial attempt fails

var f = Handlebars.compile("{{#each numbers}}{{this}}{{/each}}");
console.log(f({numbers: [1,2,3]}));
// works

var f2 = Handlebars.compile("{{#each number in numbers}}{{number}}{{/each}}");
console.log(f2({numbers: [1,2,3]}));
// fails

How do I get {{#each number in numbers}} to work in raw handlebars 2.0?

EDIT

Added a bounty here, for a handlebars extension based off https://github.com/discourse/discourse/blob/master/app/assets/javascripts/discourse/lib/ember_compat_handlebars.js that gives us each.. in support. It is clear its not built into handlebars. It is also clear Ember is able to extend this.

Upvotes: 9

Views: 1417

Answers (4)

Andrew Hacking
Andrew Hacking

Reputation: 6366

Perhaps you don't need to implement this at all since Handlebars is moving to block parameters for non context switching helpers. Ember is already using block params in 1.10 Beta (you can read about block params in the release notes).

You can use the latest builds of Handlebars to get the non context switching each with the new block params syntax right now:

var f = Handlebars.compile("{{#each numbers}}{{this}}{{/each}}");
console.log(f({numbers: [1,2,3]}));

var f = Handlebars.compile("{{#each numbers as |number|}}{{number}}{{/each}}");
console.log(f({numbers: [1,2,3]}));

Console:

"123"
"123"

Updated JSBin with the new syntax.

Upvotes: 2

whoacowboy
whoacowboy

Reputation: 7447

If I understand you question correctly, I believe this will work.

var hbs = "{{#each this}}{{this}}{{/each}}";
var f3 = Handlebars.compile(hbs);
console.log(f3({numbers: [1,2,3]}));
console.log(f3({numbers: [3,2,1]}));

http://jsbin.com/tebayupobu/4/edit

Upvotes: 2

Ed4
Ed4

Reputation: 2305

This shows how it can be done. But note that it requires the stringParams flag at compile time, which changes the way all helpers get called, so this will probably break all the other helpers unless you provide stringParams compatible versions of them.

Handlebars.registerHelper('each', function(localName,inKeyword,contextName,options){
  var list = this[contextName];
  var output = "";
  var innerContext = Object.create(this);
  for (var i=0; i<list.length; i++) {
    innerContext[localName] = list[i];
    output += options.fn(innerContext);
  }
  return output;
});

 var f = Handlebars.compile("{{#each number in numbers}}{{number}}{{/each}}", {
  stringParams: true
});

console.log(f({numbers: [1,2,3]}));

Upvotes: 4

Kingpin2k
Kingpin2k

Reputation: 47367

The non-context switching each helper is a helper introduced in Ember, it isn't part of the core handlebars library. You won't be able to use it with plain ol' handlebars.

Upvotes: 4

Related Questions