Last active
August 29, 2015 13:59
-
-
Save obenjiro/10993113 to your computer and use it in GitHub Desktop.
Shortest template engine with JavaScript support and escaping
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//this is data // noprotect | |
var context = { | |
keys:[0,1,2,3,null], | |
key:"<b>test</b>" | |
}; | |
//this is template | |
function _template(){ | |
for (var i=0; i < context.keys.length; i++) { | |
div.b; | |
if (context.keys[i] === 0) { | |
span.raw('zero').span; | |
} else { | |
partial(_item, context.keys[i]); | |
} | |
span.raw(", index: " + i).span; | |
div.e; | |
} | |
with (context){ | |
div.key.div; | |
} | |
} | |
//this is also a template but it will be called as a sub template | |
function _item(){ | |
span['class="red"']. | |
context!==null?context:'null value' | |
.span; | |
} | |
//this is an "engine" | |
function render(_template_, context, logger, escape){ | |
var result, r = "", | |
div = span = {}, | |
raw = function(t){return t;} | |
escape == null && (escape = true); | |
function partial(tmp, ctx) { return render(tmp, ctx, logger, false); } | |
escape && (context = JSON.parse(JSON.stringify(context) | |
.replace(/</g,'<') | |
.replace(/>/g,'>'))); | |
result = _template_.toString() | |
.replace(/function (\w+)\(\){/,'(function $1(){') | |
.replace(/\}$/, '})()') | |
.replace('partial(', 'r+=partial(') | |
.replace(/(div|span)\.b/g, 'r+="<$1>";') | |
.replace(/(div|span)\.e/g, 'r+="</$1>";') | |
.replace(/(div|span)(?:\['([^.']+)'\])?\./g,"r+='<$1 $2>'+(") | |
.replace(/\.(div|span)/g,')+"</$1>"') | |
; | |
logger&&logger(result); eval(result); | |
return r; | |
} | |
function compile(_template_){ | |
var result, r = "", ms, | |
div = span = {}, | |
raw = function(t){return t;} | |
result = _template_.toString() | |
.replace(/function (\w+)\(\){/,'(function $1(){') | |
.replace(/\}$/, '})()') | |
.replace('partial(', 'partial(') | |
.replace(/(div|span)\.b/g, 'r+="<$1>";') | |
.replace(/(div|span)\.e/g, 'r+="</$1>";') | |
.replace(/(div|span)(?:\['([^.']+)'\])?\./g,"r+='<$1 $2>'+(") | |
.replace(/\.(div|span)/g,')+"</$1>"') | |
; | |
var z =0; | |
while (ms = result.match(/partial\([_\w\d\.]+/g)) { | |
if (z > 100) break; | |
for (var i=0; i<ms.length; i++) { | |
var tn = ms[i].replace('partial(',''); | |
var com = compile(eval(tn), context); | |
result = result.replace(tn, com.replace('})()','})')); | |
z++; | |
} | |
} | |
return result; | |
} | |
function run(result, context, escape){ | |
var result, r = "", | |
div = span = {}, | |
raw = function(t){return t;} | |
escape == null && (escape = true); | |
escape && (context = JSON.parse(JSON.stringify(context) | |
.replace(/</g,'<') | |
.replace(/>/g,'>'))); | |
function partial(fn, ctx) { | |
var oldCtx = context; | |
context = ctx; | |
fn(); | |
context = oldCtx; | |
} | |
eval(result) | |
return r; | |
} | |
var ct = compile(_template); | |
console.time('templates render time'); | |
//calling our render function | |
for(var i =0; i < 1000; i++) {// noprotect | |
var res = run(ct, context); | |
//var res = run(compile(_template), context); | |
//var res = render(_template, context); | |
} | |
console.timeEnd('templates render time'); | |
document.body.innerHTML = res; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment