I'm considering adding an alternative to CanJS's EJS live-binding system. I really like EJS, it's extremely powerful, but ugly to look at. So, I'm trying to create a better mouse-trap.
Currently, the most popular mouse-trap seems to be Handlebars. What do you like about it?
- Syntax, or
- Prepared data
Handlebars uses {{}}
for insertion and {{#}}
and {{/}}
for widgets and control structures.
All data must be passed to handlebars (except accessed through a helper). You can not seemingly call helper methods that read data like {{person.age()}}
. This limits logic that can be performed in the template (although a helper can still do pretty much anything).
I'd like to learn what people like about handlebars and use that in the design of the alternative templating language. But, there's two issues I would have to overcome:
Prepared data is something that has been strongly promoted on the server and it also is being promoted on the client. I don't consider it as much an imperative on the client. I've never seen anyone fire an ajax call in a template. The data is always prepared, it's just accessed through the model or other helpers.
Needing prepared data makes doing something like http://jsfiddle.net/qYdwR/36/light/ with Handlebars more difficult to write. You'd have to create a computed property that is the date merged with this updating time observable.
With EJS, you can just write a function and anything that uses it becomes live.
I don't think it's possible in Handlebars, but EJS supports ERB-style sub template helpers (if you wanted to build them) like:
<%== columns(items, 4, function(item){ %>
<li><%= item.attr('name') %></li>
<% }) %>
Notice that the function(item){ ... }
is actually a template that is called out to by the columns helper implemented like:
columns = function(items, num, template){
var cols = new Array(num);
items.forEach(function(item, i){
if( ! cols[i%num] ) {
cols[i%num] = "";
}
cols[i%num] += template(item)
});
return "<ul>"+cols.join("</ul><ul>")+"</ul>";
}
And this would also instantly become live.
I'm excited to see it. Let me know if I can help in anyway.
So is EJS's output. However the output has special helpers that can.view knows about to call code for a particular element.
Yeah, I would add in a similar HTML parsing that is in EJS, making Handlebars aware where the magic tags are located.
This is the biggest problem (and I think what you mean by OK for it to use a different paradigm than EJS). I've got to look into how Ember manages this. It has to have some extra functionality that, on property lookup, looks at the context and determines if it's observable. If it is, it doesn't simply do
context[prop]
and instead, sets up binding.It's very likely I could do something similar. This would allow basic observe properties to become live. The problem then is allowing live-binding to computed values.
IMO, the
Observe.__reading
trick is freaking awesome. I'd like to still allow that by either:{{ob.foo()}}
or{{ob.foo}}
where it knows to call foo? )can.prop
as a way to create computed props.