【问题标题】:Nunjucks: Asynchronous Custom tag not working on Version > 2.3Nunjucks:异步自定义标签不适用于版本 > 2.3
【发布时间】:2020-01-14 18:09:04
【问题描述】:

使用 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); 
}

【问题讨论】:

    标签: javascript jinja2 templating nunjucks


    【解决方案1】:

    下面是如何在带有异步加载器和标签的浏览器中使用 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};
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-15
      • 2012-06-03
      • 1970-01-01
      • 2014-07-08
      • 2012-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多