Loader
加载器是一个对象,从资源(如文件系统或网络)中加载模板,以下为两个内置的加载器。A loader is an object that takes a template name and loads it from asource, such as the filesystem or network. The following two builtinloaders exist, each for different contexts.
FileSystemLoader
new FileSystemLoader([searchPaths], [opt])
只在 node 端可用,他可从文件系统中加载模板,searchPaths 为查找模板的路径,可以是一个也可以是多个,默认为当前的工作目录。
opt 为一个对象,包含如下属性:
- watch - 如果为
true
,当文件系统上的模板变化了,系统会自动更新他。使用前请确保已安装可选依赖 chokidar。 - noCache - 如果为
true
,不使用缓存,模板每次都会重新编译。
// Loads templates from the &# 34;views&# 34; folder
var env = new nunjucks.Environment(new nunjucks.FileSystemLoader('views'));
WebLoader
new WebLoader([baseURL], [opts])
只在浏览器端可用,通过 baseURL(必须为同域)加载模板,默认为当前相对目录。
opt 为一个对象,包含如下属性:
- useCache 如果为
true
,模板将会永远缓存,你将看不到他们更新。缓存默认关闭,因为这样就无法监听变化并更新缓存。记住,你应该在生产环境预编译模板。 - async 如果为
true
,模板会异步请求,而非同步,同时你必须使用异步 render API(调用render
时传入一个 callback)。
他还能加载预编译后的模板,自动使用这些模板而不是通过 http 获取,在生产环境应该使用预编译。查看 Precompiling Templates。
// Load templates from /views
var env = new nunjucks.Environment(new nunjucks.WebLoader('/views'))
Writing a Loader
你可以自己写一个更复杂一点的加载器(如从数据库加载),只需建一个对象,添加一个 getSource(name)
的方法,name 为模板名。
function MyLoader(opts) {
// configuration
}
MyLoader.prototype.getSource = function(name) {
// load the template
// return an object with:
// - src: String. The template source.
// - path: String. Path to template.
// - noCache: Bool. Don't cache the template (optional).
}
如果你希望跟踪模板的更新,并当有更新时清除缓存,这样就有一点复杂了。但你可以继承 Loader
类,可以通过 emit
方法触发事件。
var MyLoader = nunjucks.Loader.extend({
init: function() {
// setup a process which watches templates here
// and call `this.emit('update', name)` when a template
// is changed
}
getSource: function(name) {
// load the template
}
});
Asynchronous
这是最后一部分:异步加载器。到现在为止,所有的加载器都是同步,getSource
立即返回资源。这个的好处是用户不必强制使用异步 api,也不用担心异步模板的边缘问题。但是,你可以希望从数据库加载
只需在 load 中添加 async: true
属性就可支持异步调用
var MyLoader = nunjucks.Loader.extend({
async: true,
getSource: function(name, callback) {
// load the template
// ...
callback(err, res);
}
});
记住现在必须使用异步 api,查看 asynchronous support。
注意: 如果使用了异步加载器,你将不能在 for
循环中加载模块,但可以使用 asyncEach
替换之。asyncEach
和 for
相同,只是在异步的时候使用。更多查看 Be Careful!。