在express里使用doT模板引擎
发布于 10 年前 作者 lmk123 8215 次浏览 最后一次编辑是 8 年前

不知道doT模板是啥的请戳这里。这篇博文是基于截至目前最新的doT(v1.0.1)写的。

为什么使用 doT

doT是目前所有nodeJS模板引擎中最快的一个(实际上我也没测试过,但网上都这么说)。第一次注意到它,是因为无意中发现小米网的前端模板就是使用的它。

后来在项目中实际使用感觉爱不释手,果断撤掉了ejs。下一步,我就琢磨着将我这个博客的后台模板引擎也换成doT了。

将doT集成进express里?

后台使用的是express,所以当然是希望能将doT集成到express的模板引擎中去。 但后来我发现,鉴于doT独特的“预编译”(我不知道这么称呼是否准确)特性,似乎无法集成进去。

我所说的“预编译”是指,在调用

var dots = require( 'dot' ).process( { path : './views' } );

之后,doT会把 views 文件夹下的所有以 .dot 为后缀的模板都“编译”成一个函数。 例如如果你在上面的文件夹下有一个模板名叫 index.dot ,那么生成html的代码就是 dots.index();

是的,这意味着你的文件名要符合JavaScript的变量规范(例如文件名不能以数字开头)。

然而,在express里面的模板调用方法是 res.render( '这里是模板名' , { 这是数据对象 } ); ,每次调用都需要传入一个模板文件名,可是正如上面的例子所说,doT不是这么做的。

最后我发现,在 express 里面使用doT模板的方法是,把所有类似上面的代码改成:

res.send( dots[ '这里是模板名' ]( { 这里是数据对象 } ) );

同时,这意味着你没有将 doT 集成至 express 的模板引擎中,你生成的模板不会被缓存。

如果你原本使用的ejs,你还要在模板中的所有变量前加上 it. ,例如把 <%= some %>改成{{= it.some }}

使用doT引用子模板

doT的“预编译”除了支持 .dot 文件,另外还支持 .def 和 .jst 。这里只着重介绍下 .def 。

ejs里面有一个<% include some.ejs %> 语法用于加载子模板,那如何在 doT 里面实现呢?答案是:

第一步:将要被引用的模板的后缀名设为 .def ,假设它叫 some.def

第二步:在后缀名为 .dot 的模板中写 {{#def.some }} 。注意,这里不需要带上文件扩展名。

可是,doT的预编译只会将后缀名为 .dot 的文件名编译成函数。如果我既想让一个模板能成为被其他模板引用的子模板,又希望这个模板能成为一个函数呢?

答案是:为这个文件“同时使用两个扩展名”,例如 some.def.dot;至于这两个扩展名的顺序无关紧要。

这样,some.def.dot 既会成为一个函数 dots.some ,又能被其他模板使用 {{#def.some }} 引用进来。

一些提示

最后,给使用doT模板的人(以及我)的一些提示。

1、因为没有集成进 express 的模板引擎中,我需要自己进行一些优化(例如模板缓存)

2、doT“预编译”时会忽略所有子文件夹。即所有模板文件都要直接放在模板文件夹(例如./views/)下。

3、doT模板文件的文件名要遵循JavaScript变量名规范。

今天花了半天时间鼓捣了下doT,分享下结果,希望能帮到一些人,也希望能得到更好的解决方案!

6 回复

ejs 习惯了,什么都一样。

和swig很像 有啥不同? swig的文档比较好~

https://github.com/olado/doT 官网提供的express栗子 里面似乎直接没用res.render?

最短的模板引擎是哪个,是不是 John Resig的 micro template

(function(){
var cache = {};

this.tmpl = function tmpl(str, data){
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(obj){p.push(‘” +

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(”);”);

return data ? fn( data ) : fn;
};
})();

用consolidate.js使用任意模版

还是喜欢swig,虽然已经不再维护了

回到顶部