模板引擎的主要功能就是把变化的数据融入到不变的模板中,并生成最终结果。目前,前端的主要数据格式无非是XML和JSON。如何将这些数据更加方便的呈现呢?
最近看了很多的PHP模板引擎,今天看到了一个非常棒的Javascript模板引擎,用以更方便的呈现前台数据。它的一个超级简单的、快速的,高速缓存的,非常容易使用的模板引擎。
下面就来看下这个模板引擎是如何工作的。
// Simple JavaScript Templating
// John Resig - http://ejohn.org/ - MIT Licensed
(function(){
var cache = {};
this.tmpl = function tmpl(str, data){
// 判断出我们是否获取一个模板或是否我们要加载一个模板并确定要缓存结果
//Figure out if we're getting a template, or if we need to load the template - and be sure to cache the result.
var fn = !/\W/.test(str) ?
cache[str] = cache[str] ||
tmpl(document.getElementById(str).innerHTML) :
// 生成一个可作为模板的可重复使用的函数
// 生成器 (将会被缓存)
new Function("obj",
"var p=[],print=function(){p.push.apply(p,arguments);};" +
// 使用with(){} 作为局部变量引入数据
"with(obj){p.push('" +
// 将模板内容转化成JavaScript
Convert the template into pure JavaScript
str
.replace(/[\r\t\n]/g, " ")
.split("<%").join("\t")
.replace(/((^|%>)[^\t]*)'/g, "$1\r")
.replace(/\t=(.*?)%>/g, "',$1,'")
.split("\t").join("');")
.split("%>").join("p.push('")
.split("\r").join("\\'")
+ "');}return p.join('');");
// 提供一个基础的currying给用户
return data ? fn( data ) : fn;
};
})();
Currying 的意思为将原来的函数只可带一个参数列表以多个参数列表(注意不是多个参数)实现,如:def foo(x)(y)(z){}。
上面的只是具体实现的JS库,那到底怎么使用呢?
<script type="text/html" id="item_tmpl">
<div id="<%=id%>" even" : "")%>">
<div>
<img src="<%=profile_image_url%>"/>
</div>
<div>
<p><b><a href="/<%=from_user%>"><%=from_user%></a>:</b> <%=text%></p>
</div>
</div>
</script>
或是这样
<script type="text/html" id="user_tmpl">
<% for ( var i = 0; i < users.length; i++ ) { %>
<li><a href="<%=users[i].url%>"><%=users[i].name%></a></li>
<% } %>
</script>
上面的使用代码中出现了一个特别的script内容类型text/html,这样的类型浏览器就不要去执行其中的内容,用户也就看不到其中的内容。这样就可以非常简单的把你想要的内容模板嵌入到你的页面中。这是一种快速的曲线救国的策略。
讲了这么多,那么怎么把数据给模板引擎呢,这还需使用Javascript来实现:
var results = document.getElementById("results");
results.innerHTML = tmpl("item_tmpl", dataObject);
同样的你可以预先编译好需要呈现的代码供后面的使用,如下面的循环:
var show_user = tmpl("item_tmpl"), html = "";
for ( var i = 0; i < users.length; i++ ) {
html += show_user( users[i] );
以上就是全部代码,整个逻辑非常的清晰,就是把模板语言“编译”为Javascript的原生语法。这个引擎的优点在于:
- 可以使用任何Javascript支持的语法。
- Parse模板的过程在闭包内执行,不会产生全局变量。
- 对“编译”后的模板进行了缓存,下次可以跳过“编译”的过程直接使用。
最后大家还是要试一下才知道好不好用。
原代码地址:http://ejohn.org/blog/javascript-micro-templating/