/** * jQuery Templates * * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. * * Written by: Stan Lemon * * Based off of the Ext.Template library, available at: * http://www.extjs.com * * This library provides basic templating functionality, allowing for macro-based * templates within jQuery. * * Basic Usage: * * var t = $.template('
Hello ${name}, how are you ${question}? I am ${me:substr(0,10)}
'); * * $(selector).append( t , { * name: 'Stan', * question: 'feeling', * me: 'doing quite well myself, thank you very much!' * }); * * Requires: jQuery 1.2+ * * * @todo Add callbacks to the DOM manipulation methods, so that events can be bound * to template nodes after creation. */ (function($){ /** * Create a New Template */ $.template = function(html, options) { return new $.template.instance(html, options); }; /** * Template constructor - Creates a new template instance. * * @param html The string of HTML to be used for the template. * @param options An object of configurable options. Currently * you can toggle compile as a boolean value and set a custom * template regular expression on the property regx by * specifying the key of the regx to use from the regx object. */ $.template.instance = function(html, options) { // If a custom regular expression has been set, grab it from the regx object if ( options && options['regx'] ) options.regx = this.regx[ options.regx ]; this.options = $.extend({ compile: false, regx: this.regx.standard }, options || {}); this.html = html; if (this.options.compile) { this.compile(); } this.isTemplate = true; }; /** * Regular Expression for Finding Variables * * The default pattern looks for variables in JSP style, the form of: ${variable} * There are also regular expressions available for ext-style variables and * jTemplate style variables. * * You can add your own regular expressions for variable ussage by doing. * $.extend({ $.template.re , { * myvartype: /...../g * } * * Then when creating a template do: * var t = $.template("
...
", { regx: 'myvartype' }); */ $.template.regx = $.template.instance.prototype.regx = { jsp: /\$\{([\w-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g, ext: /\{([\w-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g, jtemplates: /\{\{([\w-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}\}/g }; /** * Set the standard regular expression to be used. */ $.template.regx.standard = $.template.regx.jsp; /** * Variable Helper Methods * * This is a collection of methods which can be used within the variable syntax, ie: * ${variable:substr(0,30)} Which would only print a substring, 30 characters in length * begining at the first character for the variable named "variable". * * A basic substring helper is provided as an example of how you can define helpers. * To add more helpers simply do: * $.extend( $.template.helpers , { * sampleHelper: function() { ... } * }); */ $.template.helpers = $.template.instance.prototype.helpers = { substr : function(value, start, length){ return String(value).substr(start, length); } }; /** * Template Instance Methods */ $.extend( $.template.instance.prototype, { /** * Apply Values to a Template * * This is the macro-work horse of the library, it receives an object * and the properties of that objects are assigned to the template, where * the variables in the template represent keys within the object itself. * * @param values An object of properties mapped to template variables */ apply: function(values) { if (this.options.compile) { return this.compiled(values); } else { var tpl = this; var fm = this.helpers; var fn = function(m, name, format, args) { if (format) { if (format.substr(0, 5) == "this."){ return tpl.call(format.substr(5), values[name], values); } else { if (args) { // quoted values are required for strings in compiled templates, // but for non compiled we need to strip them // quoted reversed for jsmin var re = /^\s*['"](.*)["']\s*$/; args = args.split(','); for(var i = 0, len = args.length; i < len; i++) { args[i] = args[i].replace(re, "$1"); } args = [values[name]].concat(args); } else { args = [values[name]]; } return fm[format].apply(fm, args); } } else { return values[name] !== undefined ? values[name] : ""; } }; return this.html.replace(this.options.regx, fn); } }, /** * Compile a template for speedier usage */ compile: function() { var sep = $.browser.mozilla ? "+" : ","; var fm = this.helpers; var fn = function(m, name, format, args){ if (format) { args = args ? ',' + args : ""; if (format.substr(0, 5) != "this.") { format = "fm." + format + '('; } else { format = 'this.call("'+ format.substr(5) + '", '; args = ", values"; } } else { args= ''; format = "(values['" + name + "'] == undefined ? '' : "; } return "'"+ sep + format + "values['" + name + "']" + args + ")"+sep+"'"; }; var body; if ($.browser.mozilla) { body = "this.compiled = function(values){ return '" + this.html.replace(/\\/g, '\\\\').replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.options.regx, fn) + "';};"; } else { body = ["this.compiled = function(values){ return ['"]; body.push(this.html.replace(/\\/g, '\\\\').replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.options.regx, fn)); body.push("'].join('');};"); body = body.join(''); } eval(body); return this; } }); /** * Save a reference in this local scope to the original methods which we're * going to overload. **/ var $_old = { domManip: $.fn.domManip, text: $.fn.text, html: $.fn.html }; /** * Overwrite the domManip method so that we can use things like append() by passing a * template object and macro parameters. */ /* $.fn.domManip = function( args, table, reverse, callback ) { if (args[0].isTemplate) { // Apply the template and it's arguments... args[0] = args[0].apply( args[1] ); // Get rid of the arguements, we don't want to pass them on delete args[1]; } // Call the original method var r = $_old.domManip.apply(this, arguments); return r; }; */ /* ** * Overwrite the html() method * $.fn.html = function( value , o ) { if (value && value.isTemplate) var value = value.apply( o ); var r = $_old.html.apply(this, [value]); return r; }; ** * Overwrite the text() method * $.fn.text = function( value , o ) { if (value && value.isTemplate) var value = value.apply( o ); var r = $_old.text.apply(this, [value]); return r; }; */ })(jQuery);