Search code examples
javascripttemplatescachingexternalmustache

How to cache mustache templates?


I would like to cache mustache templates.

I know that I could include mustache templates directly, like this:

<script id="mustache-template" type="text/html">
<h1>{{title}}</h1>
</script>

And call those with javascript, like this:

var html, template, data;
data = {  
    title : "Some title"
}; 
template = document.getElementById('mustache-template').innerHTML;
html = Mustache.to_html(template, data);

This won't cache templates. Only way I could figure out is usage of link -tags, but how do I call template content via javascript without an ajax request?

This won't work (of course)...

HTML

<link type="text/html" href="/mustache/template.tpl" id="mustache-template" />

Javascript

document.getElementById('mustache-template').innerHTML;

Solution

  • This question is very interesting! I had the same problem several months ago when I started to use mustache for 'huge' front-end templating within a rails project.

    I ended up with the following solution...


    Mustache templates are inside a public folder :

    /public/templates/_template_name.tpl
    

    Whenever I need a template I have this helper getTemplate that does some stuff (there's some mootools, but there are comments too):

    // namespace.templatesCache is an object ( {} ) defined inside the main app js file
    
    var 
        needXHR = false, // for callback function
        templateHTML = ""; //template html
    
    if(!(templateHTML = namespace.templatesCache[template_name])){ //if template is not cached
    
        templateHTML = (this.helpers.supportLocalStorage) ? localStorage.getItem(template_name) : ""; //if browser supports local storage, check if I can retrieve it
    
        if(templateHTML === "" || templateHTML === null){ // if I don't have a template (usually, first time), retrieve it by ajax
    
          needXHR = true;  
    
          new Request.HTML({ //or jQuery's $.get( url /*, etc */ ) 
    
              url: namespace.URLS.BASE+"templates/_"+template_name+".tpl", // url of the template file
    
              onSuccess : function(t, e, html, js){
    
                    namespace.templatesCache[template_name] = html; //cache it
    
                    if(_this.helpers.supportLocalStorage){ //and store it inside local storage, if available
                      localStorage.setItem(template_name,html); 
                    }
    
                    //call callback      
              }
          }).get();
    
        }else{ //retrieved by localStorage, let's cache it
    
            namespace.templatesCache[template_name] = templateHTML;
    
        }
    
    }
    
    if(!needXHR){ // I retrieved template by cache/localstorage, not by Ajax
    
        //call callback    
    
    }
    

    and I call this helper in this way :

    namespace.helpers.getTemplate('template_name', function( templateHTML ){
        // the callback function
    });
    

    You can notice that first time user needs the template, there's an asynch request (you could make a sync request if u don't want to wrap some other code inside the callback)

    I hope it could help and I'd love to receive feedbacks/suggestions concerning this stuff :)