Hacker News new | past | comments | ask | show | jobs | submit login
Mustache 2.0 and the Future of Mustache.js (jan.io)
57 points by pepijndevos on Feb 13, 2011 | hide | past | favorite | 41 comments



”By the time the browser has downloaded, parsed and compiled your smart compiler, my dumb parser is done rendering the template.“

Your dumb parser may be quick the first time, but when you have to render a template 100 or 1,000 or 1,000,000 times the cracks will start to show. One main benefit of parsing and compiling templates is that you can cache the result of that stage on the server.

If you want to be really smart about it, the client shouldn’t even be downloading a .mustache template — it should download a .js file containing a pre-generated function which can be called with the context, returning the rendered template. Parsing the template on the client side makes about as much sense as parsing JSON or XML with a hand-written pure-JavaScript parser.


This is valid for server side templating.

In the browser you will not render thousand times a template. And the tens milliseconds you will save if you pre-compile the template is irrelevant compared to the hundreds milliseconds of network latency and page & js load time.

I wrote http://beebole.com/pure another template engine. With the version-2 we dropped the pre-compilation. The small performance gain wasn't worth the complexity.


"And the tens milliseconds you will save if you pre-compile the template"

Ten milliseconds here, ten milliseconds there, pretty soon you're talking about real time. Especially if I can manage to browser-cache away the page & js load time you mention.


My comment supposed you need to compile the templates once. In that case the whole app is compiled once in the tens msec. Not at each rendering.


I've done this w/ my mustache implementation. Its compiled on the server side and sent down as a pure JS function.

https://github.com/josh/mustache-trimmer


On repeated compilations: Of course, hence the “Compiled Templates” requested feature.

On being "really smart": These are design goals different from mustache[.js] and can be freely implemented in any other templating library if people want it.


parsing JSON ... with a hand-written pure-JavaScript parser.

"eval"?


eval is evil. JSON.parse() is fine - neither of which is a "hand-written" parser written in JavaScript.


JSON2?


> the client shouldn’t even be downloading a .mustache template — it should download a .js file containing a pre-generated function which can be called with the context, returning the rendered template

This would render browser-side mustache as moot. Now the server side implementations must render javascript functions. handlebars.rb, handlebars.py, handlebars.php, handlebars.cs anybody?


Why would it be moot? I do something similar to this technique with haml-js and underscore templates (though i wear a full beard, i'm not really into mustache.js)

This lets me use the same views on the server and the client, with the same $templates.render("item", context); where "item.html.haml" is the name of the source file. I pre-compile the source of all the .haml files to functions and add them to the $templates object (boo, globals, yadda yadda yadda) and then write this out to a file for serving to the browser (./public/templates.js by default.)

Then, when I make a json call or whatever and need to re-render a partial, i just call the same template rendering.

Note that this works for Node.js but you could easily make it work with ruby through redcar or use a similar technique for precompiling your mustache templates for the browser while still using your language-native implementation on the server.

Edit: forgot the link https://github.com/aaronblohowiak/shared-views


> Why would it be moot?

Because the server generates the javascript template methods. Thus the browser does not need to parse the mustache templates. It only needs to call the compiled functions. This means the browser would not need to have an implementation of mustache running on it, since the template building is contained within the compiled javascript functions.


Ah, ok. I thought you meant that using the mustache template on the client side would be moot, not that having a mustache compiler on the client side would be moot. It was a little confusing because I'd still say that you are "using the mustache template" on the client side even though you are actually just running the precompiled function derived from that template.


Please look at JSON Template. http://code.google.com/p/json-template/

It solves ALL of these problems. It has {.or}, the dot notation, and searches up the stack of contexts for variables.

I haven't been working on it for awhile, mostly because it does the job, but the codebase is small and easily hackable.

EDIT: It also compiles the templates and lets you change the delimiters! And has support for several other languages.


JSON Template was around before mustache came around, it didn't win then, I don't know if it will win now. I want to improve the Mustache line, not make people switch to something else.

As an alternative, it looks good, so thanks for bringing it up.


I don't really think of it as "winning or losing". It's not like a general purpose programming language with large network effects (e.g. you may depend on a library with 100k sloc). The switching cost is pretty low, especially since they both use JSON as the data model.


JSON template looks nice. Great feature set.

I don't know about the python version, but I had a look at the Javascript code for json-template. At first look it seems pretty "hacky". The main obvious flaws I saw were:

- it's polluting the global namespace a lot. Introducing a lot of functions and variables. - it's roughly 800 lines, while mustache.js is just over 300. I realize json template has more features. - A lot of the javascript could do with some optimization. Especially some of the loops.

But maybe that's something you simply want help with?


Everything is wrapped in the "jsontemplate" namespace. It's just not indented.

If you have some speedups I'm open to it, although I think it is pretty fast as it doesn't parse the template on every expansion.


Mustache has an equivalent to {.or}

{{^something}} {{/something}}

The draw of mustache is that it does things implicitly. I don't have to worry about .section, .repeated, .or, |html, for example. Mustache does it for me.

That being said, one thing that mustache does need to address is the difference between conditionals and repeated operations as needed (handled by .section and .repeated in JSON Template).

AFAIK, the songs template would require a boolean to be passed in of the existence of songs in mustache, since mustache would implicitly assume that {{#songs}} was a loop and create multiple tables.

http://json-template.googlecode.com/svn/trunk/doc/Introducin...


If you read the linked article, you'd see that I am calling for an {.or}-like construct to avoid having to use inverted sections for a fake else-case.


Got it. I guess the distinction is not that big of a deal for me, though it would be nice to have the inline {.or}-like construct (it saves one statement).


You can set the default formatter to "html" if you want (or any other formatter). It probably could be better documented.

You seem to be on the fence about if you want an explicit "repeated" or not. I haven't thought about it too much but it seems cleaner to be explicit. I don't want to confuse an object {} and a singleton array [{}].


Yes to else sections. The lack of else is just plain annoying after awhile.

Don't care on dotted access.

Context addressing is fine if we can agree on a method and keep the spec simple. Perhaps using Git's SHA addressing with things like HEAD, HEAD^, HEAD^^ or similar.

Yes to booting dynamically changing delimiters.

Yes to stealing helpers.

For cross-language compatibility, we really should have a collection of test inputs and outputs.

We should adopt a directive thing like you have for the 'this' notation with {{.}} or whatever for lists. The original is a bit funny looking but I think this sort of thing would fix the delimiter issue.

Another pattern that I run into that's a bit weird is when I need to add markup around a list when its not empty. I end up having a context that returns a context with a rows object when there is data, or None when there are no rows. So it looks like this in mustache:

{{#genes}} open table {{#rows}} row stuff {{/rows}} end table {{/genes}}

I keep having the feeling there's a better way to make that work.

If I get another project finished up shortly I'll write these up in a branch of pystache.


> For cross-language compatibility, we really should have a collection of test inputs and outputs.

https://github.com/mustache/spec


> {{#genes}} open table {{#rows}} row stuff {{/rows}} end table {{/genes}}

JSON templates has an interesting solution.

http://json-template.googlecode.com/svn/trunk/doc/Introducin...

{.section genes} open table {.repeated section @} row stuff {.end} end table {.end}


I move to jquery-tmpl because I never understood why there was so much resistance to the dot notation.

BTW, jQuery-tmpl is supposed to become "jQuery/DOM" free in a few, which allow to use it on the server-side as well (assuming Javascript).


This is a good point.

Most programmers are familiar with the common notations for nested structures (e.g.: a dot, or a slash). Mustache's solution requires a programmer to explicitly reference the parent context: https://github.com/defunkt/mustache/issues/issue/6#issue/6/c...

https://gist.github.com/3c91441597ac650146b9

Maybe this was to keep Mustache "pure", and avoid introducing a dot- or slash- syntax. "Turtles all the way down"?

I agree the syntax is clunky. But it does have some internal logic.

I'd argue that the bigger problem is: most people don't know the feature exists.


How are people using these JavaScript templating frameworks? What is the structure and flow of the application? They seem interesting but I don't yet totally grasp what benefits they provide.


In the case of a web app, the main benefit for me is you outsource the rendering of the HTML to the,usually idle, browser. Your server is freed to deliver only data.

And for recurrent visitors. The logic(HTML, CSS, JS) is in the browser's cache. Then only data travel the network from the 2nd visit, freeing even more your server.


They're useful for doing more on the client than server. If your UI runs only on the client then you just have to write a web service to communicate with. You just take the V out of MVC, or you have views that simply emit JSON/XML/whatever.

Most web pages would not benefit from this but many web apps can and do.


I like the goals. I wish 2.0 was ready now. I'm only tangentially interested in non-JavaScript versions. Fixing the merged contexts and getting dot-notation are the killer new features. I'd use this as soon as it becomes available.

I hope you don't get bogged down waiting for consensus from the "mustache community". Better to implement and put a stake in the ground, I think.


There are enough forks that implement these things today, see the Network and issue tracker on gh:/janl/mustache.js.


The problem is too many forks. Over 100 now. As a practical matter, which one would you recommend using that would be the most accurate preview of the new feature set in Mustache 2.0.


If there were one I wouldn't be calling for 2.0 :D — Sorry, you gotta dig for yourself.


Yeah, I remember the first time I've installed and used Mustache with IcanHaz. It was.. really a pure moment. And then, x.y didn't work and I went crying. Even last week, I had to explain to a new developer why our templates doesn't have the x.y notation and instead have a {{#x}{{y}.. {{/wtf}} notation.

So, I'd be totally willing to help on that part :)


I was curious about this one, but my use case would have been Javascript and Python, and when I looked a few weeks back, the Python version out there couldn't even handle all the examples in the man page.

I'll have to keep an eye on the 2.0 project.


Hmm.. why not use something similar to like Django/Jinja syntax? {{ x }} for variable related items, and {% %} for logic related if/else/ifnotequal etc... things.


As a user of mustache in multiple languages, I believe the most important priority of the mustache community is to have uniform implementations, which is what the mustache spec will hopefully solve.

There are some features that do not seem to be consistent across implementations. For example, partial templates are handled differently in mustache.rb and mustache.js.

It seems like there are attempts to "embrace and extend" the mustache language (handlebars and mustache.js), which is fine, as long as the spec is adhered to and the good features get folded into the spec.


Thanks for reinforcing this view. I want to make sure this is one of the overarching goals, which is why I listed it in the Design Principles.

The difference between .rb and .js stems from JS lacking File.read(). But a 2.0 spec could work around that.


Rendering members of Arrays should also be in the spec. I believe mustache.js has support for changing the iterator rendering token, however mustache.rb does not.

{ "items": ["foo", "bar"] }

# From mustache.rb

{{#items}} {{{to_s}}} {{/items}}


I propose we have a mustache convention at the end of November (grow a mustache month). Those without mustaches will be shunned and not taken seriously (those unable to grow naturals can wear fake stashes)!




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: