javascripttemplatesunderscore.jsjquery-globalization

Combine jQuery Globalize with underscore.js template?


I'm using an underscore template to create an HTML list, this list contains a date field that I would like to globalize. A simplification of the template looks like this:

<li>Date: <%= date %> </li>

This date is a Javascript date object, so don't want to print the value directly, I would like to print it using globalize. Without the template the solution should look like this:

var html = "<li>Date: " + Globalize.format(settings.get('lastUpdate'),'F') + "</li>";

Do you think I can use the template to achieve this or I must use a workaround?


Solution

  • You can call any globally accessible function inside your template. So, if Globalize is global (i.e. a property of window), then this template:

    <script id="tmpl" type="text/html">
        <li>Date: <%= Globalize.format(date, 'F') %></li>
    </script>
    

    will work with this JavaScript:

    _.template($('#tmpl').html(), {
        date: some_date_that_globalize_understands
    });
    

    If you don't have Globalize globally available then you could:

    window.Globalize = Globalize;
    

    to make it globally available or just add it to the template's namespace manually:

    _.template($('#tmpl').html(), {
        Globalize: Globalize,
        date:      some_date_that_globalize_understands
    });
    

    Demos:

    1. Global Globalize through window.Globalize..
    2. Local Globalize through the _.template parameters..

    There's really nothing special about the Underscore templates, the stuff inside <%= %> is just JavaScript code that ends up wrapped in a with block. You can even see the function's source by looking at the source property on the returned template function:

    var t = _.template($('#t').html());
    console.log(t.source);
    

    and you'll see some fairly simple (if ugly) JavaScript like this:

    function(obj){
    var __p='';var print=function(){__p+=Array.prototype.join.call(arguments, '')};
    with(obj||{}){
    __p+='\n    '+
    ( Globalize.mangle(pancakes) )+
    '\n';
    }
    return __p;
    }
    

    That + (Globalize.mangle(pancakes) )+ bit is what <%= Globalize.mangle(pancakes) %> gets turned into. No magic, no special parsing of the contents of <%= ... %>, just a simpleminded (but effective) conversion to JavaScript.