jQote2 API reference
jQote2’s internals are quite a bit different from its predecessor’s. Thus, please make sure to double-check the new API as it breaks backward compatibility!
The three biggest changes with jQote2’s API are:
- it now returns a “stringified” representation of your generated HTML markup
- it’s now possible to precompile your templates to closures (no need to deliver template markup within your documents anymore)
- it now supports on-the-fly templating strings
Here’s a quick overview of jQote2 ’s new interface:
- .jqote(data[, tag])
- .jqoteapp(template, data[, tag])
- .jqotepre(template, data[, tag])
- .jqotesub(template, data[, tag])
$(template).jqote(data[, tag]) : function
jQote2 is able to operate on an arbitrary number of templates, each of which may process an arbitrary number of data objects, thus effectively allowing you to trigger n:m conversions with a single call.
Each time a template of yours is run, it is passed a couple of auxiliary variables:
-
two counting variables
iandj
(the former iterating over the processed templates, the latter iterating over your data objects array) -
the data objects array
dataitself -
the current processed template’s compiled lambda
fn
(which comes in handy with recursive calls)
To not be forced to use data[j] to access a template’s current data object, its compiled lambda is fired in the context of the data object, so you may just as well use the this keyword to reference your data.
Additionally, during the process of conversion (the execution of the lambda, that is) you may access the by then converted output using the out variable. This gives you total control over the output even from within a template at any time.
By the way: all of the above is also true for any of the jqoteXXX convenience methods explained below.
Returns
out : string (the processed outcome)
Parameters
data : object | array of object
One or more objects that carry the template’s dynamic data. Each data object that’s passed in here will get merged with any of the templates you called the conversion upon.
tag : string (optional, defaults to "%")
You may use the optional tag parameter to specify different template tag character(s) for a single conversion. Keep in mind though that whatever char(s) C you opt for here will result in <C ... C>.
Called upon
template : jQuery object
Every template within the jQuery collection will be merged with any of your data objects.
Example
The infamous and obligatory “Hello World” … generated with a different start- and ending tag (the * star).
Note: data[j] is essentially the same as this!
<p id="example"></p>
<script type="text/x-jqote-template" id="template">
<![CDATA[
I said <strong><*= this.greet + " " + data[j].who *></strong> !!!
<* out = out.replace(/John/, 'World'); *>
]]>
</script>
<script type="text/javascript">
// let's do some jQote magic
$('#example').append(
$('#template').jqote({greet: 'Hello', who: 'John'}, '*')
);
</script>
I said Hello World !!!
$(elem).jqoteapp(template, data[, tag]) : function
This is one of three convenience methods jQote2 has to offer. It allows you to append the processed template’s outcome directly to any DOM element that is part of the jQuery object.
Returns
jQuery : jQuery object
The returned jQuery object keeps the method chain intact. It is the same object that you called the convenience method upon.
Parameters
template : jQuery object | jQuery selector |
DOM element | array of DOM element |
lambda | array of lambda |
template string
This parameter can be passed as about anything you possibly could think of. It’ll work with a collection of template elements (either as jQuery object or array of DOM elements) as well as single template elements (again jQuery object or DOM element).
Furthermore you could pass it a single or multiple (just wrap them up in an array) precompiled lambda which gets you the best performance as it will skip the compilation and execute right away.
For quick and dirty on-the-fly templating you may also choose to supply a template string which won’t get cached but other than that behaves just as any other template.
data : object | array of object
tag : string (optional)
Called upon
elem : jQuery object
The outcome of the conversion will be appended to every single DOM element within the jQuery object.
Example
The “Hello World” example from above rewritten.
<p id="example"></p>
<script type="text/html" id="template">
<![CDATA[
I said <strong><%= this.greet + " " + this.who %></strong> !!!
<% out = out.replace(/John/, 'World'); %>
]]>
</script>
<script type="text/javascript">
// let's do some jQote magic
$('#example').jqoteapp('#template', {greet: 'Hello', who: 'John'});
</script>
I said Hello World !!!
Example
This makes use of the on-the-fly templating support.
<ul id="example"></ul>
<script type="text/javascript">
$('#example').jqoteapp(
'<li><<%= this.tag %>>Styled!</<%= this.tag %></li>',
[ {tag: 'strong'}, {tag: 'em'} ]
);
</script>
- Styled!
- Styled!
$(elem).jqotepre(template, data[, tag]) : function
This is jqoteapp’s counterpart as it behaves just the same way with one major difference: it prepends the outcome rather than appends it.
Returns
jQuery : jQuery object
Parameters
template : jQuery object | jQuery selector |
DOM element | array of DOM element |
lambda | array of lambda |
template string
data : object | array of object
tag : string (optional)
Called upon
elem : jQuery object
$(elem).jqotesub(template, data[, tag]) : function
If you need to substitute an element’s “innerHTML” more than once, this function is for you. It replaces whatever resides within a DOM element with the outcome of your template’s processing.
Returns
jQuery : jQuery object
Parameters
template : jQuery object | jQuery selector |
DOM element | array of DOM element |
lambda | array of lambda |
template string
data : object | array of object
tag : string (optional)
Called upon
elem : jQuery object
Example
Replace the target’s “innerHTML” with something more “up to date” …
<p id="up_to_date"></p>
<script type="text/javascript">
$(function() {
var now = function() {
return new Date().toString().replace(/ GMT.*$/, '');
};
$('#up_to_date').bind('uptodate', function() {
var self = $(this);
setTimeout(function() {
self.jqotesub('<%= this.date %>', {date: now()})
.triggerHandler('uptodate');
}, 1000);
}).triggerHandler('uptodate');
});
</script>
$.jqote(template, data[, tag]) : function
This basically offers the same functionality as its object associated counterpart with the added possibility to have it process precompiled lambdas or on-the-fly template strings.
Returns
out : string (the processed outcome)
Parameters
template : jQuery object | jQuery selector |
DOM element | array of DOM element |
lambda | array of lambda |
template string
data : object | array of object
tag : string (optional)
Example
Calculating the famous Fibonacci sequence (using just a small n due to Javascript’s limited recursion stack).
<ul id="fibonacci">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<script type="text/x-jqote-template" id="template">
<![CDATA[
<%= ( ( this.n == 0 ) ?
0 : ( this.n == 1 || this.n == 2 ) ?
1 : parseInt($.jqote(fn, {n: this.n-1})) +
parseInt($.jqote(fn, {n: this.n-2})) ) %>
]]>
</script>
<script type="text/javascript">
$(function() {
var lambda = $.jqotec('#template');
$('#fibonacci li').each(function(i) {
$(this).text($.jqote(lambda, {n: i}));
});
});
</script>
$.jqotec(template[, tag]) : function
This is jQote2’s heart, its engine that powers the template parsing and lambda generation. It transforms a single template into a compiled function that – once processed – is cached internally to speed up successive usage.
You may assign the returned lambda to a variable and/or pass it to any of the before mentioned functions or let jQote2 fetch it from its internal cache for you (just pass the associated DOM element in this case).
Please note that on-the-fly template strings won’t get cached as there’s no element to associate the lambda to. Moreover, if for whatever reason you need to recompile a cached template, jQote2 makes sure to replace the cached lambda for you.
Returns
lambda : function
The compiled lambda is merely a Javascript function like any other. Once called and fired in the context of a data object the lambda returns a “stringified” representation of your template’s and data object’s merge. In most cases this will be an “HTML string”, though it could be anything that goes into a string (i.e. plain text or a JSON string etc.).
The lambda’s signature is defined as: λ(i, j, data, fn), where fn is a reference to λ (this is important when you need to have recursion within your templates).
For an explanation of what each paramter stands for, see this paragraph.
Parameters
template : jQuery object | jQuery selector |
DOM element |
template string
Please note that only the very first template of a set of matched templates within a supplied jQuery object (or selected by means of a jQuery selector) is chosen for compilation.
tag : string (optional)
Example
See what the lambda of above’s “Hello World” example looks like once it’s been compiled.
<pre id="lambda"></pre>
<script type="text/x-jqote-template" id="template">
<![CDATA[
I said <strong><*= this.greet + " " + this.who *></strong> !!!
<* out = out.replace(/John/, 'World'); *>
]]>
</script>
<script type="text/javascript">
$(function() {
$('#lambda').text(
$.jqotec('#template', '*').toString()
);
});
</script>
$.jqotefn(template) : function
jQote2 exposes its internal cache $.jqotecache and gives access to a template’s compilate by means of the its DOM element’s internal cache ID (just a plain integer starting at zero and running up). This cache ID is assigned to the template’s DOM element and may be read with elem.jqote or $(template selector)[0].jqote.
As it is a tedious task to type in $.jqotecache[$('#mytmpl')[0].jqote] over and over, you may as well just use the more convenient way: $.jqotefn('#mytmpl') !!!
Returns
lambda : function (or false if nonexistent)
Parameters
template : jQuery object | jQuery selector |
DOM element
$.jqotetag(string) : function
Calling this function you will be able to permanently alter jQote2's default tag char from being % to something more suitable to your needs.
Returns
void
Parameters
tag : string
You aren't forced to have a single tag char, at all. You might just as well use some crazy ass string like ^^. Keep in mind though, that whatever char(s) you opt for you always have to prepend/append angle brackets within your templates!
comments
11 Responses to “jQote2 API reference”
Leave a Reply
Can you explain how one might create and manage numerous templates without having script tags all over the place? I”m using EJS right now which fetches a template with ajax which is great because i can create as many .ejs template files as I want and I never muddy up my html source with script tags. I’m looking for something more jquery friendly however as I’d like to start associating data with my dom elements as they’re rendered. Can you provide a sample of how this might be achieved? or does one always need a tag in order to use jqote?
@Brad
Hi Brad. No, those script tags aren’t required at all. They’re just a handy way to embed templates within your pages without being rendered or indexed by search engines. You could just as well wrap a div around your templates and use the tag’s display property to hide it.
Anyways, you asked for a way to remotely include your templates. There are quite a bunch of options to choose from, mostly depending on the way you organize your templates. To list them here would go beyond the scope of a single post, but to get you started consider the following:
A template file foo.tpl that contains a single template …
<h1>Hello world!</h1> <p> My name is <%= this.name %> and I really love <%= this.what %>. </p>… and some Javascript to let it run …
Nice. This was easy, wasn’t it? A one file per template approach gives the benefit of not having to wrap up your template markup with some kind of dummy container.
However, if you need to combine several templates within a single file, you would have to put these in a container (you may use any tag for this, even custom ones) and assign an ID or at least a class name to be able to select these later on.
From an email I once wrote to a jQote2 user:
<template id="tmpl_1"> // some template markup </template> <template id="tmpl_2"> // some template markup </template> ...Ok, I think you’ll grasp the concept. Hope this gets you started.
Regards.
Hi! How about introducing
<%! value %>to mimic the current<%= value %>and switching<%= possibly_unescaped_value %>to always perform HTML escaping so it can be safely used?TIA,
–Vladimir (via GitHub)
I really like your examples showing how to use multiple templates loaded via ajax calls but I find there is a problem with jquery parsing the retrieved html and replacing the template tags (<%) with html entities (<). I've tried all sorts of ways to get around this but can't find a solution. Have you successfully used this template loading method in a test?
I’m getting “Uncaught ReferenceError: ” in Chrome… it doesn’t report a useful line number (line 2).
I’m stumped. What should I be looking for?
Cheers
@Rich
The latest release of jQote2 (i.e. v0.95) provides some basic error handling. All you need to start debugging is a decent JavaScript debugger (preferably Firebug or Firebug lite, in your case). Some quick hints on how to debug:
Wrap the method invocation in a try/catch block like so:
try { .... $('div.my_container').jqoteapp(...); } catch (e) { console.dir(e); }This provides you with an error object that contains the call stack, the lambda (i.e. converted template function), the arguments that were passed to your template and a type variable that indicates what kind of jQote2 error has been raised.
Of particular interest are the template function and the type variable: if you get a “TemplateCompilationError” than your template could not be compiled which indicates that there’s some sort of syntax error within your template’s source. A “TemplateExecutionError” on the other hand is most likely caused by some sort of unresolvable reference(s) or runtime errors, in which case you should examine the compiled template itself using the error object mentioned earlier. To see what’s causing the compiled template to fail you could copy the lambda’s source and use it like any other JavaScript function like so:
<script type="text/x-jqote-template" id="err_tmpl"> <![CDATA[ <p>What's the problem here, <%= that.name %>?</p> ]]> </script> <script type="text/javascript"> // First, let's get the compiled template's source // which we'll be copying to the clipboard and ... console.log( // I may be commented out after my source was leaked :) $.jqotec('err_tmpl').toString() ); // ... pasting into our site's source, renaming it to // something descriptive and removing the try/catch block function bugged(i, j, data, fn) { //try { var out = "<p>What's the problem here, "; out += that.name; out += "?</p>"; return out; /*} catch (e) { e.type = "TemplateExecutionError"; e.args = arguments; e.template = arguments.callee.toString(); throw e; }*/ } // Now, we will provide the buggy lambda with some // sample data to have it choke on and generate // a decent JavaScript exception var dummy = {name: 'Kenneth'}; bugged.call(dummy, 0, 0, [dummy], bugged); </script>Happy debugging.
Regards,
aefxx
OK, thanks!
One more question.
I now have this working beautifully in the browser. However I’d like to use it in an Adobe Air app.
Air has a sandbox restriction where you can’t call “new Function” after the onload event.
So, to use templates in an Air app, I figure the best way is to pre-compile the templates?
Would you be so kind as to give an example of using this plugin to pre-compile and render templates?
many thanks
never mind i figured it out…
// to precompile a template
TEMPLc = $.jqotec($(‘#templ_id’))
// returns templated output as string
$.jqote(TEMPLc, data)
I have the following problem that I would like to solve with jQote2.
data: [ { set: 1, tmpl: 'a', .. }, { set: 2, tmpl: 'b', .. }, { set: 3, tmpl: 'a', .. }, { set: 4, tmpl: 'c', .. } .. and so on ]; <script type="text/x-jqote-template" id="tmpl_a"></script> <script type="text/x-jqote-template" id="tmpl_b"></script> <script type="text/x-jqote-template" id="tmpl_c"></script>I would like to render the above within one div so it looks like so
tmpl_a output with set 1
tmpl_b output with set 2
tmpl_a output with set 3
tmpl_c output with set 4
..
and so on
In other words, I have a sequence of data sets that I want to render with set-specific templates. Can this be done?
never mind… I figure it out… ;-)
for (var i = 0; i < data.length; i++) { $('#example').append( $('#' + LCA.data[i].tmpl).jqote(LCA.data[i]) ); }Hi. I’ve been using jqote for a couple months now and it’s a great tool. I’m in the process of changing my app to load my templates dynamically and am pretty stumped. Basically, none of the template tags are being parsed at all. Here’s an example of a simple template that is working when it’s embedded locally:
CURRENT PLAYLIST:
<% for(i=0; i
<option value="”>
After running it through $.jqotec I get this:
function anonymous(i, j, data, fn) {
var out=”";out+=’ CURRENT PLAYLIST: ‘; return out;
}
Which I notice has converted some characters in their html entity equivalents. I’m sure I must be missing something pretty simple. Anyone point me in the right direction?