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;
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 :)
You could try to load your template in an iframe
that contains an HTML page(that will be cached) with all your script
tags inside.
Then you can read them from the main page, or push them from the iframe to the parent
window.
That is what I do when using pure.js templates
What you say it will not work, of course, because the innerHTML attribute of the liknek element will not give you the contents of the link.
You can use Chevron to load external templates from links like so:
You add in you template a link to your template file:
<link href="path/to/template.mustache" rel="template" id="templateName"/>
Then, in you JS you can render your template like so:
$("#templateName").Chevron("render", {name: "Slim Shady"}, function(result){
// do something with 'result'
// 'result' will contain the result of rendering the template
// (in this case 'result' will contain: My name is Slim Shady)
});
The docs of Chevron will give more examples
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With