Skip to content

Instantly share code, notes, and snippets.

@gustavopaes
Created September 9, 2013 17:20
Show Gist options
  • Save gustavopaes/6498757 to your computer and use it in GitHub Desktop.
Save gustavopaes/6498757 to your computer and use it in GitHub Desktop.
underplate it's just the template engine used by underscore Lib. I just removed all underscore code to can use the good template engine. All code here was writed by underscore team, it's not my own. Based at Underscore.js 1.5.2.
/**
* underplate it's just the template lib used by underscore lib. I just
* removed all underscore code to can use just the good template engine.
*
* All code here was writed by underscore team.
*
* Based at Underscore.js 1.5.2
*
* @licence The MIT License (MIT)
*/
var underplate = (function() {
var _ = {};
_.keys = Object.keys || function(obj) {
if (obj !== Object(obj)) throw new TypeError('Invalid object');
var keys = [];
for (var key in obj) if (obj.hasOwnProperty(key) === true) keys.push(key);
return keys;
};
// List of HTML entities for escaping.
var entityMap = {
escape: {
'&': '&',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#x27;'
},
unescape: {
'&amp;': '&',
'&lt;': '<',
'&gt;': '>',
'&quot;': '"',
'&#x27;': "'"
}
};
// Regexes containing the keys and values listed immediately above.
var entityRegexes = {
escape: new RegExp('[' + _.keys(entityMap.escape).join('') + ']', 'g'),
unescape: new RegExp('(' + _.keys(entityMap.unescape).join('|') + ')', 'g')
};
// At the original underscore code, this function is in
// a each loop.
var escaping = function(method) {
return function(string) {
if (string == null) return '';
return ('' + string).replace(entityRegexes[method], function(match) {
return entityMap[method][match];
});
};
}
_.escape = escaping('escape');
_.unescape = escaping('unescape');
// By default, Underscore uses ERB-style template delimiters, change the
// following template settings to use alternative delimiters.
var templateSettings = {
evaluate : /<%([\s\S]+?)%>/g,
interpolate : /<%=([\s\S]+?)%>/g,
escape : /<%-([\s\S]+?)%>/g
};
// When customizing `templateSettings`, if you don't want to define an
// interpolation, evaluation or escaping regex, we need one that is
// guaranteed not to match.
var noMatch = /(.)^/;
// Certain characters need to be escaped so that they can be 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;
// JavaScript micro-templating, similar to John Resig's implementation.
// Underscore templating handles arbitrary delimiters, preserves whitespace,
// and correctly escapes quotes within interpolated code.
return function(text, data, settings) {
var render;
settings = (function(target) {
for(var t in templateSettings) {
if(templateSettings.hasOwnProperty(t) === true && target.hasOwnProperty(t) === false) {
target[t] = templateSettings[t];
}
}
return target;
}(settings || {}));
// Combine delimiters into one regular expression via alternation.
var matcher = new RegExp([
(settings.escape || noMatch).source,
(settings.interpolate || noMatch).source,
(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, offset)
.replace(escaper, function(match) { return '\\' + escapes[match]; });
if (escape) {
source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
}
if (interpolate) {
source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
}
if (evaluate) {
source += "';\n" + evaluate + "\n__p+='";
}
index = offset + match.length;
return match;
});
source += "';\n";
// If a variable is not 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";
try {
render = new Function(settings.variable || 'obj', '_', source);
} catch (e) {
e.source = source;
throw e;
}
if (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;
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment