下面是如何在带有异步加载器和标签的浏览器中使用 nunjucks。
import '/js/vendors/nunjucks.min.js';
// Define custom async loader
var MyLoader = nunjucks.Loader.extend({
async: true,
getSource: function(path, cb) {
fetch('/templates/' + path)
.then(res => res.text())
.then(src => cb(null, {src, path, noCache: false}))
.catch(cb);
}
});
// Define environment with custom loader
var env = new nunjucks.Environment(new MyLoader(), {autoescape: true});
// Define custom tag "get" to load remote data by url to var
// Example:
// {% get book = '/api/books/10' %}
// {{ book.id }} {{ book.name }}
function GetExtension(cb) {
this.tags = ['get'];
this.parse = function(parser, nodes, lexer) {
var tok = parser.nextToken();
var args = parser.parseSignature(null, true);
parser.advanceAfterBlockEnd(tok.value);
return new nodes.CallExtensionAsync(this, 'run', args, cb);
};
this.run = function(context, args, cb) {
let ref = args instanceof Object &&
Object.keys(args).filter(e => e != '__keywords')[0];
var url = args[ref];
var headers = {pragma: 'no-cache', 'cache-control': 'no-cache'}
fetch(url, {headers})
.then(res => res.json())
.then(function (res) {
if (res.error)
console.error(url, res.error);
context.ctx[ref] = res.error ? undefined : res;
cb && cb();
})
.catch(cb);
};
}
env.addExtension('GetExtension', new GetExtension());
// Example of async filter (similar to `include`-tag)
// Usage: {{ 'template-name.njk' | render({a: 10, text: 'OK'}) }}
env.addFilter('render', function (template, ctx, cb) {
env.render(template, ctx,
(err, html) => cb && cb(err, !err ? env.filters.safe(html) : undefined)
);
}, true);
// Example of sync filter
env.addFilter('time', function (datetime) {
return new Date(+datetime).toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'});
});
export {env as njk};