在express里使用Nodejs的doT模板引擎
在express里使用Nodejs的doT模板引擎
不知道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
,分享下结果,希望能帮到一些人,也希望能得到更好的解决方案!
在express里使用Nodejs的doT模板引擎
为什么使用 doT
doT
是目前所有 Node.js 模板引擎中最快的一个(实际上我也没测试过,但网上都这么说)。第一次注意到它,是因为无意中发现小米网的前端模板就是使用的它。后来在项目中实际使用感觉爱不释手,果断撤掉了 ejs
。下一步,我就琢磨着将我这个博客的后台模板引擎也换成 doT
了。
将doT集成进express里?
后台使用的是 Express,所以当然是希望能将 doT
集成到 Express 的模板引擎中去。 但后来我发现,鉴于 doT
独特的“预编译”(我不知道这么称呼是否准确)特性,似乎无法集成进去。
我所说的“预编译”是指,在调用以下代码后,doT 会把 views 文件夹下的所有以 .dot
为后缀的模板都“编译”成一个函数:
var dots = require('dot').process({ path: './views' });
例如,如果你在上面的文件夹下有一个模板名叫 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
模板的人(以及我)的一些提示。
- 因为没有集成进
express
的模板引擎中,我需要自己进行一些优化(例如模板缓存) doT
“预编译”时会忽略所有子文件夹。即所有模板文件都要直接放在模板文件夹(例如 ./views/)下。doT
模板文件的文件名要遵循 JavaScript 变量名规范。
今天花了半天时间鼓捣了下 doT
,分享下结果,希望能帮到一些人,也希望能得到更好的解决方案!
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使用任意模版
要在Express中使用doT模板引擎,你需要手动处理模板的渲染过程,而不是通过Express的默认模板引擎机制。以下是一个简单的示例来展示如何在Express应用中使用doT。
示例代码
-
安装必要的依赖:
npm install express dot
-
创建一个简单的Express应用,并配置doT:
const express = require('express');
const dot = require('dot');
// 初始化Express应用
const app = express();
const port = 3000;
// 加载并预编译所有 .dot 模板
const dots = dot.process({ path: './views' });
// 设置静态文件目录
app.use(express.static('public'));
// 渲染doT模板
app.get('/', (req, res) => {
const data = {
title: 'Hello World',
message: 'This is a message from the server'
};
res.send(dots['index'](data));
});
app.listen(port, () => {
console.log(`Server running on http://localhost:${port}`);
});
- 在
views
文件夹中创建一个名为index.dot
的模板文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{= it.title }}</title>
</head>
<body>
<h1>{{= it.message }}</h1>
</body>
</html>
-
启动服务器:
node app.js
-
访问
http://localhost:3000
查看结果。
解释
- 预编译模板:使用
dot.process
函数预编译所有.dot
模板文件。 - 渲染模板:在路由处理函数中,使用预编译后的模板函数
dots['index']
来渲染模板,并传递数据对象。 - 静态资源:可以使用
express.static
中间件来提供静态文件服务。
这种方式虽然没有集成到Express的模板引擎中,但可以通过手动方式实现模板的渲染和数据传递。