I’ve started looking into using Knockout for my team’s use; I’ve been very pleased with the framework so far, with the exception of its ties to the jQuery Templates plugin, whose syntax I hate. Additionally (and more importantly), we’ve been using jQote2 for our client-side templating, so I wanted to look into creating a template engine that uses it.
I’m having difficulty with the renderTemplate function; the jQote2 library doesn’t seem to know how to locate the variables passed in through the data argument. Has anyone dealt with this sort of thing before? I’m assuming it’s more of a jQote2 quirk than anything with how Knockout renders its templates…
The code:
jqoteTemplateEngine = function () {
var templates = {};
this.createJavaScriptEvaluatorBlock = function (script) {
return '<%= ' + script + ' %>';
}
this.getTemplateNode = function (template) {
var templateNode = document.getElementById(template);
if (templateNode == null)
throw new Error("Cannot find template with ID of " + template);
return templateNode;
}
this.renderTemplate = function(templateId, data, options) {
var renderedMarkup = jQuery.jqote(templates[templateId], data);
return ko.utils.parseHtmlFragment(renderedMarkup);
}
this.rewriteTemplate = function (template, rewriterCallback) {
var templateNode = this.getTemplateNode(template);
templates[template] = rewriterCallback(templateNode.text);
}
this.isTemplateRewritten = function (templateId) {
return templateId in templates;
}
};
jqoteTemplateEngine.prototype = new ko.templateEngine();
ko.setTemplateEngine(new jqoteTemplateEngine());
The Gist: http://gist.github.com/1341737
I would take a look at KO 1.3. It is in beta, but is quite stable. Two important things in 1.3. There is now a native template engine, so you could choose to avoid having any dependency on an external template engine (and even jQuery). The control-flow bindings with anonymous templates make this much simpler option.
Secondly, it simplified the way that custom template engines are defined. So, if you still want to use an external engine, then it is a bit easier to get it working.
Basically, you only need to define a
renderTemplatemethod and acreateJavaScriptEvaluatorBlockif you want to be able to data-bind to variables available to the template engine. The rest is defined on ako.templateEnginebase “class”.So, your engine might simply look like:
Here is a sample in use: http://jsfiddle.net/rniemeyer/yTzcF/