Search code examples
javascripttemplatesbackbone.jsmarionette

Marionette: Loading external Handlebars template files


What I want to do is to configure Marionette to load external Handlebars template files instead of doing <script id="templateId" type="text/template">...</script>.

I stumbled upon @Derick Bailey's post at External handlebars templates backbone marionette ... but apparently, it doesn't work for me as I'm getting the same "callback is undefined", as pointed out by one of the comments. I'm using Marionette 2.2.0... by the way.

This is what I have come out with:-

Backbone.Marionette.Renderer.render = function ( templateId, data ) {
    console.log( "render() - " + templateId + " " + JSON.stringify( data, null, 4 ) );

    var promise = Backbone.Marionette.TemplateCache.get( templateId );

    $.when( promise ).done( function ( template ) {
        console.log( "render() - promise fulfilled - " + template );
        return template( data );
    } );
};

Backbone.Marionette.TemplateCache.prototype.loadTemplate = function ( templateId ) {
    console.log( "loadTemplate() - " + templateId );
    var tmpId = templateId.replace( "#", "" ),
        url = "resources/js/templates/" + tmpId + ".html";

    var renderer = $.Deferred();
    $.get( url, function ( templateHtml ) {
        console.log( "loadTemplate() - URL get - " + templateHtml );
        renderer.resolve( Handlebars.compile( templateHtml ) );
    } );

    return renderer.promise();
};

While, I'm not getting any errors, I'm also not seeing any rendered template on the screen.

Looking at the Firebug console, I'm seeing the following....

enter image description here

How do I fix it? I have spent several hours trying to solve this, but I'm getting frustrated now.

Thanks much.


Solution

  • I have figured out the solution of this problem:-

    Backbone.Marionette.TemplateCache.prototype.loadTemplate = function ( templateId ) {
        var template = '',
            url = 'resources/js/templates/' + templateId + '.html';
    
        // Load the template by fetching the URL content synchronously.
        Backbone.$.ajax( {
            async   : false,
            url     : url,
            success : function ( templateHtml ) {
                template = templateHtml;
            }
        } );
    
        return template;
    };
    
    // Instruct Marionette to use Handlebars.
    Marionette.TemplateCache.prototype.compileTemplate = function ( template ) {
        return Handlebars.compile( template );
    };
    

    If you want to load external Underscore template files instead, then you can safely omit Marionette.TemplateCache.prototype.compileTemplate so that Marionette will use Underscore template, which is the default.