[英]Nunjucks: Asynchronous Custom tag not working on Version > 2.3
使用nunjucks版本3.2.0異步自定義標簽無效,但使用版本2.3.0則有效; 2.3.0以上的任何版本都不起作用。
parse ( parser, nodes, lexer ) {
let tok = parser.nextToken();
let args = parser.parseSignature(null, true);
parser.advanceAfterBlockEnd(tok.value);
return new nodes.CallExtensionAsync(this, 'run', args);
}
run ( context, args, callback ) {
setTimeout(() => {
let tag = "<div><h1>Title</h1></div>"
callback(null, new nunjucks.runtime.SafeString(tag));
}, 2000);
}
下面是如何在帶有異步加載器和標記的瀏覽器中使用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};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.