Edit in JSFiddle

var UI = {};

UI.Modal = (function() {
    /**
     * Shows waiting message
     */
    function showWaitingMessage() {
        showContent("Patience is a virtue...");
    }
    /**
     * The main show content function.
     * @param content content can be actual data or a Deferred/Promise object.
     */
    function showContent(content) {
        $.when(content).then(
            function(data) {
                $.fancybox($.isArray(data) ? data[0] : data);
            }, 
            function() {
                showContent("Ooops! There seems to be a problem :(");
            });
    }
    return {
        showWaitingMessage: showWaitingMessage,
        showContent: showContent
    }
}());

UI.Templating = (function() {
    /**
     * Compiles the template and applies data to the template.
     * @param source handlebars template source
     * @param data actual data NOT a deferred object
     * @return string the html
     */
    function applyData(source, data) {
        var template = Handlebars.compile(source);
        return template(data); 
    }
    /**
     * Gets the html
     * @param source actual template source or a Deferred/Promise object
     * @param data actual data or a Deferred/Promise object
     * @return the actual html or a Promise object
     */
    function toHtml(source, data) {
        // no need to create deferred object if both arguments are already stringss
        if(typeof source == "string" && typeof data == "string")
            return applyData(source, data);
        var dfd = $.Deferred();
        $.when(source, data).then(
            function(arg1, arg2) {
                dfd.resolve(applyData($.isArray(arg1) ? arg1[0] : arg1, $.isArray(arg2) ? arg2[0] : arg2));
            },
            function() {
                dfd.reject(); 
            }                        
        );
        return dfd.promise();
    }
    return {
        toHtml: toHtml
    }
}());

$("#show-modal").on("click", function(e) {
    UI.Modal.showContent("Wow... that's quick!");
});

$("#show-modal-ajax-data").on("click", function(e) {
    UI.Modal.showWaitingMessage();
    // simulate data request
    var dfd = $.ajax({
        type: "POST",
        url: "/echo/json/",
        data: {json: JSON.stringify("Simple message"), delay: 1},
        dataType: "json"
    });
    UI.Modal.showContent(dfd);
    e.preventDefault();
});

$("#show-modal-ajax-data-tpl").on("click", function(e) {
    UI.Modal.showWaitingMessage();
    // simulate data request
    var dfdData = $.ajax({
        type: "POST",
        url: "/echo/json/",
        data: {json: JSON.stringify({name: "See Wah"}), delay: 1},
        dataType: "json"
    });
    // simulate template request
    var dfdTpl = $.ajax({
        type: "POST",
        url: "/echo/html/",
        data: {html: "Hello from <b>{{name}}</b>!", delay: 1},
        dataType: "html"
    });
    UI.Modal.showContent(UI.Templating.toHtml(dfdTpl, dfdData));
    e.preventDefault();
});
<input type="button" id="show-modal" value="Show me the modal!">
<br>
<input type="button" id="show-modal-ajax-data" value="Show me the modal! (ajax data)">
<br>
<input type="button" id="show-modal-ajax-data-tpl" value="Show me the modal! (ajax data AND ajax template)">

              
            
          
            
              

External resources loaded into this fiddle: