不知道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
,分享下结果,希望能帮到一些人,也希望能得到更好的解决方案!