Greg Funtusov
Greg Funtusov

Reputation: 1447

Manually use precompiled handlebars templates

How to manually use the precompiled handlebars.js templates?

Let's say, we have

source = "<p>Hello, my name is {{name}}</p>"
data = { name: "Joe" }

Currently, I have

template = Handlebars.compile(source)
render: -> template(data)

The source is coming from the database, and in order to cut down on the compilation time, I want to use a compilation step, precompiling the template server side with Handlebars.precompile(source) and then using something like:

template = precompiled_template
render: -> precompiled_template(data)

The precompiled_template is a string with function definition, so that doesn't work.

Also, I've found that Hanlebars.compile(source)() == Handlebars.precompile(source), but after browsing the source codes of handlebars, it's compilers and runtime, I'm still not sure how to achieve this.

Upvotes: 5

Views: 8346

Answers (2)

Greg Funtusov
Greg Funtusov

Reputation: 1447

This speed test http://jsperf.com/handlebars-compile-vs-precompile/3 gave the answer.

Apparently, one solution is to eval() that resulting string and it will work.

The code is

var data = { name: "Greg" };
var source = "<p>Howdy, {{ name }}</p>";

eval("var templateFunction = " + Handlebars.precompile(source));
var template = Handlebars.template(templateFunction);

template(data);
=> "<p>Howdy, Greg</p>" 

Of course one needs to be careful with eval and probably a better solution exists.

Upvotes: 0

Daniel
Daniel

Reputation: 111

if you did not find the right question till now, the answer is pretty simple. Handlebars comes with a C pre-compiler on the command line, if you can access your shell you can simple just compile your templates each separated or merge them together into one file.

you can install Handlebars via npm / or build it on your system. on the shell you can access the help file

$> Handlebars [ENTER]

You will see a help file like > - f --output Output File etc etc .. - m --min Minimize Output

$> Handlebars mysupertemplate.handlebars -f compiled.js -m ("-m" if you want to minify the js file)

To run Handlebars.compile in the browser is a huge loss in performance, so it's worth a try to precompile on the server before sending the file to the browser.

To register Handlebars templates in your browser you have to load them like this:

var obj = {"foo":"bar"}

var template = require("./mytemplate-file.js") // require.js example
    template = template(Handlebars) // Pass Handlebars Only if the template goes mad asking for his Father

var html = Handlebars.templates[template-name](obj)

For example if you have more then one template registered in the "templates-file" you will be able to access after the require call all templates by name using

var html = Handlebars.templates["templateName"]({"foo":"bar"});

You can go even further by register all the know helper within the file and / or making custom helpers for partials like so..

*// This will be the helper in you app.js file*

Handlebars.registerHelper("mypartials", function(partialName, data) {
     var partial = Handlebars.registerPartial(partialName) || data.fn
     Handlebars.partials[partialName] = partial
})

And in your template file you can put this...

{{#mypartial "divPartial"}}
  <div id="block"><h2>{{foo}}</h2><p>{{bar}}</p></div>  
{{/mypartial}}

{{#mypartial "formPartial"}}
  <form id="foo"><input type="text" value="{{foo}}" name="{{bar}}"></form>
{{/mypartial}}

Now you can access this files by calling

var html = Handlebars.partials["divPartial"]({"foo":"bar","bar":"foo"})
var formHtml = Handlebars.partials["formPartial"]({"bar":"bar","foo":"foo"})

Hope this helped a bit ..

Upvotes: 4

Related Questions