gruntjs / grunt-contrib-handlebars

Precompile Handlebars templates to JST file.
http://gruntjs.com/
MIT License
282 stars 126 forks source link

Partials with runtime.js #49

Closed danactive closed 10 years ago

danactive commented 11 years ago

Do you have sample code on how-to use partials with the handlebars-runtime.js?

tkellen commented 11 years ago

I don't personally use this plugin any longer, but @pdokas might.

pdokas commented 11 years ago

I do, but I’m unclear about what exactly you’re wondering @danactive. Generally speaking, Handlebars will compile your partials like normal templates and where other templates invoke a partial the compiler will generate a line similar to:

stack1 = self.invokePartial(partials['detail-view'], 'detail-view', depth0, helpers, partials, data);

From this point, as long as you have all of the needed templates and the Handlebars runtime loaded you should be good to go. Could you ask a more specific question, @danactive?

danactive commented 11 years ago

I haven't tried your exact example syntax, but when I look at the handlebars-runtime.js code I see compile method is required

https://raw.github.com/wycats/handlebars.js/1.0.0-rc.3/dist/handlebars.runtime.js Line 312 if (!Handlebars.compile) { throw new Handlebars.Exception("The partial " + name + " could not be compiled when running in runtime-only mode");

My code snippet is Handlebars.registerPartial("listingCount", JST["./Templates/ListingCount.html"]);

danactive commented 11 years ago

@pdokas I see my precompiled templates have similar code as your sample. What I'm asking about is how do I use the template from the client side after the precompile has occurred. I currently register my partial Handlebars.registerPartial("listingCount", JST["./Templates/ListingCount.html"]);

But I get an error message when I try to use the master template return JST"./Templates/RDC/ListingInfo.html";

I'm getting this error message https://raw.github.com/wycats/handlebars.js/1.0.0-rc.3/dist/handlebars.runtime.js Line 312 if (!Handlebars.compile) { throw new Handlebars.Exception("The partial " + name + " could not be compiled when running in runtime-only mode");

-=Dan=-

pdokas commented 11 years ago

@danactive Sorry about the delay in getting back to you, thanks for the reminder to do so!

What I'm seeing is that you’re not precompiling your partials which handlebars-runtime.js requires you to do. What leads me to believe this is that your partials are being registered like this:

Handlebars.registerPartial("listingCount", JST["./Templates/ListingCount.html"]);

Whereas a successful compilation of a partial should be generated out to something like:

Handlebars.registerPartial("PARTIAL_NAME", Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {
...

Or if you have partialsUseNamespace set to true, it'll look like:

Handlebars.registerPartial("PARTIAL_NAME", this["YOUR_NAMESPACE"]["PARTIAL_NAME"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {

I personally use a config like this:

options: {
    namespace: 'Templates',
    wrapped: true,
    partialsUseNamespace: true,
    partialsPathRegex: /\/partials\//,
    partialRegex: /.*\.handlebars$/,

    processName: function(fileName) {
        var bits = fileName.split('/');
        return bits[bits.length - 1].replace('.handlebars', '');
    },

    processPartialName: function(fileName) {
        var bits = fileName.split('/');
        return bits[bits.length - 1].replace('.handlebars', '');
    }
},
files: {
    expand: true,
    cwd: 'common/templates/',
    src: ['**/*.handlebars'],
    dest: 'build/js/templates/',
    flatten: true,
    ext: '.js'
}
danactive commented 11 years ago

Okay, I'm starting to see where you're going. You're bypassing the missing runtime.js compile method by defining your own function Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {

But what code would be inside that anonymous function?

-=Dan=-

pdokas commented 11 years ago

I would say it’s more that you can use grunt-contrib-handlebars to compile your partials ahead of time, just like a normal function.

The compiled function – beginning with Handlebars.template(function (Handlebars,depth0,helpers,partials,data) { – is generated by this grunt task and through being identified as a partial by the options partialRegex, partialsPathRegex, partialsUseNamespace, and processPartialName, they’re compiled with a Handlebars.registerPartial() wrapper.

bluemaex commented 11 years ago

@pdokas nice, was about asking a kind of same question, but your last code-snippet solved all my questions and problems. Thank you! Works wonderfully now :+1:

btipling commented 11 years ago

This issue thread was super helpful in explaining how to use partials in run time only.