模板引擎
允许您在Express中使用静态模板文件。在运行时,模板引擎用实际值替换模板文件中的变量,并将模板转换为HTML文件发送到客户端。这种方法使得设计HTML页面更容易。
常见的模板引擎有:
设置模板引擎
Express可以通过如下方式来这是应用的模板引擎
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
以上模板引擎的设置,会根据设置的'view engine'
值,自动引入模板引擎的NPM
包,所以在此之前必须要安装pug
npm install pug --save
它等价于以下写法:
const pug = require('pug');
app.set('views', path.join(__dirname, 'views'));
app.engine('pug', pug.__express);
源码解析
模板引擎的关键代码主要在两个文件中:express/lib/application.js,express/lib/view.js。
express/lib/application.js
app.engine = function engine(ext, fn) {
if (typeof fn !== 'function') {
throw new Error('callback function required');
}
// get file extension
var extension = ext[0] !== '.'
? '.' + ext
: ext;
// store engine
this.engines[extension] = fn;
return this;
};
app.render = function render(name, options, callback) {
...
// view
if (!view) {
var View = this.get('view');
view = new View(name, {
defaultEngine: this.get('view engine'),
root: this.get('views'),
engines: engines
});
if (!view.path) {
var dirs = Array.isArray(view.root) && view.root.length > 1
? 'directories "' + view.root.slice(0, -1).join('", "') + '" or "' + view.root[view.root.length - 1] + '"'
: 'directory "' + view.root + '"'
var err = new Error('Failed to lookup view "' + name + '" in views ' + dirs);
err.view = view;
return done(err);
}
// prime the cache
if (renderOptions.cache) {
cache[name] = view;
}
}
...
}
express/lib/view.js
function View(name, options) {
...
if (!opts.engines[this.ext]) {
// load engine
var mod = this.ext.substr(1)
debug('require "%s"', mod)
// default engine export
var fn = require(mod).__express
if (typeof fn !== 'function') {
throw new Error('Module "' + mod + '" does not provide a view engine.')
}
opts.engines[this.ext] = fn
}
...
}
开发模板引擎
由上所知,我们有两种方式来开发Express的模板引擎:
- 通过
app.set('view engine', engineName)
方法,自动引入方式 - 通过
app.engine(ext, fn)
方法,注册模板引擎方式
这两种方法,本质上是一致的,暂只介绍第二种方式
// engineExt: 模板文件扩展名
app.engine(engineExt, function(filepath, options, callback){
// filepath: 模板文件的路径
// options: 渲染模板所用的参数
// callback: 渲染完成回调
// 参数一:渲染过程的错误,如成功,则为null
// 参数二:渲染出来的字符串
return callback(null, 'Hello World');
});
举个例子:
app.set('views', './views');
app.engine('tmpl', function(filepath, options, callback){
return callback(null, 'Hello World');
});
// 通过源码知道,此处并不需要
app.set('view engine', 'tmpl');
// 转换为HTML到客户端
app.get('/', function (req, res) {
res.render('index', { title: 'Hello World'})
});
混合使用多种模板引擎
在render方法上只要带上文件扩展名,Express就会根据扩展名加载相应的模板引擎。
app.get('/index.jade', function (req, res, next) {
res.render('index.jade', {title: 'jade'});
});
app.get('/index.ejs', function (req, res, next) {
res.render('index.ejs', {title: 'ejs'});
});
这篇文章目前没有评论