2 * jQuery Templating Plugin
3 * NOTE: Created for demonstration purposes.
4 * Copyright 2010, John Resig
5 * Dual licensed under the MIT or GPL Version 2 licenses.
8 // Override the DOM manipulation function
9 var oldManip = jQuery.fn.domManip;
12 render: function( data ) {
13 return this.map(function(i, tmpl){
14 return jQuery.render( tmpl, data );
18 // This will allow us to do: .append( "template", dataObject )
19 domManip: function( args ) {
20 // This appears to be a bug in the appendTo, etc. implementation
21 // it should be doing .call() instead of .apply(). See #6227
22 if ( args.length > 1 && args[0].nodeType ) {
23 arguments[0] = [ jQuery.makeArray(args) ];
26 if ( args.length === 2 && typeof args[0] === "string" && typeof args[1] !== "string" ) {
27 arguments[0] = [ jQuery.render( args[0], args[1] ) ];
30 return oldManip.apply( this, arguments );
35 render: function( tmpl, data ) {
38 // Use a pre-defined template, if available
39 if ( jQuery.templates[ tmpl ] ) {
40 fn = jQuery.templates[ tmpl ];
42 // We're pulling from a script node
43 } else if ( tmpl.nodeType ) {
44 var node = tmpl, elemData = jQuery.data( node );
45 fn = elemData.tmpl || jQuery.tmpl( node.innerHTML );
48 fn = fn || jQuery.tmpl( tmpl );
50 // We assume that if the template string is being passed directly
51 // in the user doesn't want it cached. They can stick it in
52 // jQuery.templates to cache it.
54 if ( jQuery.isArray( data ) ) {
55 return jQuery.map( data, function( data, i ) {
56 return fn.call( data, jQuery, data, i );
60 return fn.call( data, jQuery, data, 0 );
64 // You can stick pre-built template functions here
68 * For example, someone could do:
69 * jQuery.templates.foo = jQuery.tmpl("some long templating string");
70 * $("#test").append("foo", data);
75 _default: [ null, "$i" ],
76 prefix: "jQuery.each($1,function($2){with(this){",
87 prefix: "_.push(typeof $1==='function'?$1.call(this):$1);"
91 prefix: "_.push($.encode(typeof $1==='function'?$1.call(this):$1));"
95 encode: function( text ) {
96 return text != null ? document.createTextNode( text.toString() ).nodeValue : "";
99 tmpl: function(str, data, i) {
100 // Generate a reusable function that will serve as a template
101 // generator (and which will be cached).
102 var fn = new Function("jQuery","$data","$i",
103 "var $=jQuery,_=[];_.data=$data;_.index=$i;" +
105 // Introduce the data as local variables using with(){}
106 "with($data){_.push('" +
108 // Convert the template into pure JavaScript
110 .replace(/[\r\t\n]/g, " ")
111 .replace(/\${([^}]*)}/g, "{{= $1}}")
112 .replace(/{{(\/?)(\w+|.)(?:\((.*?)\))?(?: (.*?))?}}/g, function(all, slash, type, fnargs, args) {
113 var tmpl = jQuery.tmplcmd[ type ];
116 throw "Template not found: " + type;
119 var def = tmpl._default;
121 return "');" + tmpl[slash ? "suffix" : "prefix"]
122 .split("$1").join(args || (def?def[0]:null))
123 .split("$2").join(fnargs || (def?def[1]:null)) + "_.push('";
125 + "');}return $(_.join('')).get();");
127 // Provide some basic currying to the user
128 return data ? fn.call( this, jQuery, data, i ) : fn;