Underscore Template Plugin Customization
Add Features:
1. Nested templates
2. Support Render Filter Mode {{A | filtera:arg1.}}
3. Cache (consider joining Localstorage?) )
4. Commissioning
Todo
Performance optimization
Asynchronous rendering
The code is as follows
<!--Lang:js--(function (_) {_.templatesettings = {evaluate:/{% ([\s\s]+?) %}/g, Interpolate:/{{([\s\s]+?)}} /g, Escape:/{%-([\s\s]+?) %}/g, include:/{%include ([\s\s]+?) %}/g, Iscache:true, Isdebug:true,}; When customizing ' templatesettings ', if you don't want to define AN//interpolation, evaluation or escaping regex, We need one that's//guaranteed not to match. var nomatch =/(.) ^/; Certain characters need to being escaped so, they can is put into a//string literal. var escapes = {"'": "'", ' \ \ ': ' \ \ ', ' \ R ': ' r ', ' \ n ': ' n ', ' \ t ': ' t ', ' \u2028 ': ' u2028 ', ' \u2029 ': ' u2029 '}; var escaper =/\\| ' | \r|\n|\t|\u2028|\u2029/g; /** * Reference Template * Add: * Filter, can exist data, or global filters inside *///gloabal filter var filters = _.filters = {},//template Cache class Tplcache = {}; _.addfilters = fUnction (obj, fn) {if (typeof obj = = ' object ') {_.extend (filters, obj); } else if (typeof obj = = ' string ') {_.extend (filters, {OBJ:FN}); }} _.template2 = function (text, data, settings) {settings = _.defaults ({}, settings, _.templatesettings); The template is introduced outside the Include (function Replaceinclude () {text = Text.replace (settings.include, function (MATC H, result) {var url = $.trim (result) var ret = syncgettpl (URL) return ret })//template also has template if (settings.include.test (text)) {replaceinclude (); }}) ()//Combine delimiters into one regular expression via alternation. var matcher = new RegExp ([(Settings.escape | | nomatch). SOURCE, (Settings.interpolate | | nomatch). So Urce, (settings.evaluate | | nomatch). SOURCE].join (' | ') + ' |$ ', ' G '); //Compile The template source, escaping string literals appropriately. var index = 0; var Source = "__p+="; Text.replace (Matcher, function (match, escape, interpolate, evaluate, offset) {source + = Text.slice (index, off Set). replace (Escaper, function (match) {return ' \ \ ' + Escapes[match]; }); if (escape) {source + = "' +\n ((__t= (" + Escape + ")) ==null? ': _.escape (__t)) +\n '"; }//Parse property expression, support filter//example:value|fn2:a1,a2|fn3:b1,b2,b3 if (interpolate) { SOURCE + = "' +\n ((__t= (" + getassemblefnstr () + ") ==null? ': __t) +\n '"; } function Getassemblefnstr () {var filterchain = interpolate.split (' | '), CURFILTERIDX =-1; var filterstack = []; return _ (Filterchain). Reduce (function (val, filter) {//filter has two kinds; one function, another functionname if (filter.length) {curfilteridx++; var fname = filter.split (': '), name = Fname[0], args = fname[1] | | ", Callfnstr = new Function (' x ', ' Return x '); Name is function Str//var namefn = new function (' Return name ') () var exp = '; if (Name.indexof (' function ') >-1) {exp = ' var Filterfunc = name;\n ' + ' Return name.apply (_,_.flatten ([' +val+ ', Args.split (",")])) '; }//debug mode Else if (name = = ' Debug ') {var bef Orefilter = Filterchain[curfilteridx], Beforefiltername = Beforefilter.split (': ') [0], BEFOREFILTERFN = BeforefilTername.indexof (' function ') >-1? BEFOREFILTERNAME:FILTERS[BEFOREFILTERNAME] exp = ' \ n (function () {\ n ' + ' var fv = ' +val+ '; \ n ' + (Settings.isdebug? ("Console.debug (\" Filter: "+ beforefilter +" \ "); \ n" + "Console.debug (\"%coutput:\ "+FV" + ", ' color:red '); \ n" + (Curfilteridx > 0?) "Console.debug (\" FILTERFN: "+ beforefiltername +": \ "," + BEFOREFILTERFN + "); \ n": ")) : ";" ) + ' \nreturn fv; ' + ' \ n} ' () \ n '; } else {if (Filters[name]) {exp = ' (' + Filters[name] + ') ' + ' (' + val + (args.length? (', ' + args): ') + ') ' } else {console.error (' [' + name + ']filter: doesnt exist! ') exp = val; }} return exp; } else {return val; }})} if (evaluate) {source + = "'; \ n" + Evaluate + "\n__p+="; } index = offset + match.length; return match; }); SOURCE + = "'; \ n"; If A variable is isn't specified, place data values in local scope. if (!settings.variable) Source = ' With (obj| | {}) {\ n ' + source + '}\n '; Source = "Var __t,__p=", __j=array.prototype.join, "+" print=function () {__p+=__j.call (arguments, ');};\ N "+ source +" return __p;\n "; var render; try {render = new Function (settings.variable | | ' obj ', ' _ ', source); } catch (e) {e.source = source; Throw e; } if (Data && _.size (data)) return render (data, _); var template = function (data) {return Render.call (this, data, _); }; Provide the compiled function source as a convenience for precompilation. Template.source = ' function (' + (settings.variable | | ' obj ') + ') {\ n ' + source + '} '; return template; }; _.TPL = function (Htmlselectorortplurl, RenderData, Renderdomseletor, RENDEREDFN) {var htmloriginal = $ (htmlselect orortplurl). HTML (), T1 = _.now (), COMPILEDFN = function (html) {var TPL = _.template2 (HTML); var t2 = _.now () $ (renderdomseletor). HTML (TPL (RenderData)); var t3 = _.now () Debug (' time-consuming analysis ', ' tpl.source ', ' \n[ms]compile ', ' t2-t1 ', ' Render: ', ' t3-t2 ', ' total ', T3-T1) RENDEREDFN? RendEredfn.apply (this): null; }; if ($.trim (htmloriginal) = = ") {//ajax request get template $.get (Htmlselectorortplurl, function (HTML) { COMPILEDFN (HTML)})} else {COMPILEDFN (htmloriginal)}} funct Ion Debug (Group) {if (_.templatesettings.isdebug) {console.group (group); _ ([].slice.call (arguments, 1)). Each (function (text) {console.log (text); }) Console.groupend (); }} function Syncgettpl (htmlselectorortplurl) {//If a URL as a selector comes in and throws an exception,//hack:var html = ' ‘; Cache if (_.templatesettings.iscache && Tplcache[htmlselectorortplurl]) {return tplcache[ht Mlselectorortplurl]; try {if ($ (htmlselectorortplurl). length) {html = $ (htmlselectorortplurl). html (); } else {AJ (); }} catch (e) {AJ (); } function aj () {$.ajax ({url:htmlselectorortplurl + '? ' + _.now (), Type: ' Get ', Async:false, Success:function (resp) {html = RESP }})} if (_.templatesettings.iscache) {Tplcache[htmlselectorortplurl] = html; } return HTML; }})(_)
Underscore.js Template Extensions