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,不使用缓存,模板每次都会重新编译。
  1. // Loads templates from the &# 34;views&# 34; folder
  2. 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
  1. // Load templates from /views
  2. var env = new nunjucks.Environment(new nunjucks.WebLoader('/views'))

Writing a Loader

你可以自己写一个更复杂一点的加载器(如从数据库加载),只需建一个对象,添加一个 getSource(name) 的方法,name 为模板名。

  1. function MyLoader(opts) {
  2. // configuration
  3. }
  4. MyLoader.prototype.getSource = function(name) {
  5. // load the template
  6. // return an object with:
  7. // - src: String. The template source.
  8. // - path: String. Path to template.
  9. // - noCache: Bool. Don't cache the template (optional).
  10. }

如果你希望跟踪模板的更新,并当有更新时清除缓存,这样就有一点复杂了。但你可以继承 Loader 类,可以通过 emit 方法触发事件。

  1. var MyLoader = nunjucks.Loader.extend({
  2. init: function() {
  3. // setup a process which watches templates here
  4. // and call `this.emit('update', name)` when a template
  5. // is changed
  6. }
  7. getSource: function(name) {
  8. // load the template
  9. }
  10. });

Asynchronous

这是最后一部分:异步加载器。到现在为止,所有的加载器都是同步,getSource 立即返回资源。这个的好处是用户不必强制使用异步 api,也不用担心异步模板的边缘问题。但是,你可以希望从数据库加载

只需在 load 中添加 async: true 属性就可支持异步调用

  1. var MyLoader = nunjucks.Loader.extend({
  2. async: true,
  3. getSource: function(name, callback) {
  4. // load the template
  5. // ...
  6. callback(err, res);
  7. }
  8. });

记住现在必须使用异步 api,查看 asynchronous support

注意: 如果使用了异步加载器,你将不能在 for 循环中加载模块,但可以使用 asyncEach 替换之。asyncEachfor 相同,只是在异步的时候使用。更多查看 Be Careful!