oirodolfo
6/23/2016 - 5:16 PM

AMD style, testable templates fetcher

AMD style, testable templates fetcher

define([
    "jquery",
    "require",
    "handlebars",
    "util/Util",
    "../../template/CompiledTemplates" // required so to load the pre-compiled templates pushed there during build
], function ($, require, Handlebars, Util, CompiledTemplates) {

    /**
     * Retrieve template from handlebars file.
     * Useful during dev cycle so you wouldn't have to compile your templates all the time
     * Hangs the result on the
     * @param {string} name
     * @returns {Promise} resolved with compiled template, rejected if can't load template
     */
    function getTemplateForDev(name) {
        var dfd = new $.Deferred();

        // require this dynamically so it won't compile the Handlebars dev into our production code
        require([
            "handlebars-dev"
        ],
            function (Handlebars) {
                $.ajax({
                    url: 'template/' + name + '.handlebars',
                    success: function (data) {
                        // resolve with compiled template
                        dfd.resolve( Handlebars.compile(data) );
                    },
                    fail: function() {
                        // failed to load template dynamically, probably not there
                        dfd.reject();
                    }
                });
            });

        return dfd.promise();
    }

    /**
     * Dev aid function to allow using pre-compiled templates as well as bare .handlebars files templates during dev process
     * @param {string} name of template
     * @returns {Promise} resolved with compiled template, rejected if can't load template
     */
    function getTemplate(name) {
        var dfd = new $.Deferred();

        Handlebars.templates = Handlebars.templates || {};
        if (Handlebars.templates[name] === undefined) {
            // in dev mode we load template dynamically
            if (Util.isDebugMode()) {
                getTemplateForDev(name)
                    .then(function(template) {
                        // hang the newly dynamically loaded and compiled template where all templates usually go
                        // for next usages
                        Handlebars.templates[name] = template;
                        // resolve with dynamically loaded and compiled template
                        dfd.resolve(template);
                    })
                    .fail(function () {
                        // failed to load the template dynamically, probably isn't there
                        dfd.reject();
                    });
            } else {
                // reject as template not found and we're in production mode, so can't load handlebar templates
                dfd.reject();
            }
        } else {
            // template exists, resolve with it
            dfd.resolve(Handlebars.templates[name]);
        }
        return dfd.promise();
    }

    return {
        getTemplate: getTemplate
    };
});