Underscore.js Template Extensions

Source: Internet
Author: User

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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.