Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 738
Sam Saffron Avatar asked Jan 05 '15 01:01

Sam Saffron


4 Answers

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]}));
like image 147
Ed4 Avatar answered Oct 09 '22 21:10

Ed4


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.

like image 29
Kingpin2k Avatar answered Oct 09 '22 22:10

Kingpin2k


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

like image 29
whoacowboy Avatar answered Oct 09 '22 20:10

whoacowboy


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.

like image 41
Andrew Hacking Avatar answered Oct 09 '22 22:10

Andrew Hacking