众所周知,Express阵营中视图模板大多是Jade或则ejs,使用起来简单高效。既然是模板,那就需要规定好模板语言的格式,比如jade的缩进格式,ejs的<% %>
。
那么,什么时候需要自定义视图模板引擎呢?对了,就是当模板语言是自定义的时候。不幸,我们在项目中就遇到了这种需求,所以需要自己实现一个模板引擎。所幸,在Express中使用一个自定义视图引擎是非常简单。往下看。
相关API:
app.engine(ext, callback)
app.set(name, value)
这里简单概括下:
使用app.engine(ext, callback)
创建视图引擎,其中ext
是模板文件的后缀名, callback
的函数签名为function(filePath, options, callback)
,其中
filePath
是模板文件的路径
options
是数据对象,常用来替换模板中的占位符
callback
回调的签名是function(err, renderedHtml)
使用app.set('view engine', 'ext')
配置Application Settings,注册自己的视图引擎,其中ext是模板文件的后缀名
Show Me The Code
先准备好一个Express的骨架工程,删除关于view engine的配置
删除app.js中下面的代码(如果有,或者jade):
1 2 3
| app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'ejs');
|
替换为自定义的视图引擎:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| var fs = require('fs'); app.engine('abc', function(filePath, options, callback) { fs.readFile(filePath, function(err, content) { if (err) { return callback(new Error(err)); } var rendered = content.toString() .replace('#name#', options.name) .replace('#age#', options.age); return callback(null, r endered); }) }); app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'abc');
|
注册路由:
1 2 3 4 5 6
| app.use('/', function(req, res, next) { res.render('index.abc', { name: 'le0zh', age: 31 }); });
|
在views文件夹中添模板文件index.abc:
1 2 3 4 5 6 7 8 9 10 11 12
| <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>自定义模板引擎测试</title> </head> <body> <h3>自定义模板引擎测试</h3> <p>姓名: #name#</p> <p>年龄: #age#</p> </body> </html>
|
完成之后,启动Express:
使用浏览器访问,可以看到渲染后的页面啦。
更进一步
上面的例子中,我们的模板引擎非常简单,当它复杂起来时,一大坨的代码在app.js中,影响阅读。
下面我们模块化,将模板引擎提出来,新建一个myViewEngine.js
文件,把引擎的逻辑放进去:
1 2 3 4 5 6 7
| var fs = require('fs'); var myViewEngine = function(filePath, options, callback) { }; module.exports = myViewEngine;
|
现在,在app.js中只需要:
1 2 3 4 5 6 7
| var myViewEngine = require('./myViewEngine'); app.engine('abc', myViewEngine); app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'abc');
|
剩下的工作,就是丰富myViewEngine.js
的功能了。