nunjucks函数参数未定义

gar*_*ary 8 javascript nunjucks

我已经使用nunjucks几个月,并发现它是一个伟大的模板引擎.然而,今天早上我遇到了一个看似简单的问题,但我根本想不出来.我希望另一组眼睛可以帮助指出解决方案.

问题:如果我将一个函数传递给一个模板,那么传递给该函数的任何参数都是在函数体内未定义的.

值和对象可以毫无问题地传递给模板,如果我传递一个函数,我可以从函数内部登录到控制台(所以我知道函数本身就在那里),但参数都是未定义的.

这最初看起来像是可以通过闭包解决的东西,但是1)我在任何可以找到的例子中看不到闭包,2)当我尝试闭包时,我发现它们也接收到未定义的参数.

在一天的过程中,我将我的代码缩回到最简单的可能情况,但仍然无法弄清楚这一点:

模板:

<div>

<p>{{ value }}</p>

<p>{{ object|pretty }}</p>

<p>{{ func(4) }}</p>

<p>{{ args(4)|pretty }}</p>

<p>{{ local(4) }}</p>

</div>
Run Code Online (Sandbox Code Playgroud)

呈现模板的代码(这是在requirejs中定义的,未显示):

    var nunjucks = require('lib/nunjucks-slim.min'), // v1.3.4
        env = new nunjucks.Environment(null), // global templates
        $tgt = $('#test'),
        local;

    env.addGlobal('value', 3);

    env.addGlobal('object', {
        a: 2
    });

    env.addFilter('pretty', function (obj) {
        return JSON.stringify(obj, null, 2);
    });

    env.addGlobal('func', function (val) {
        return 'func: ' + val;
    });

    env.addGlobal('args', function () {
        return arguments;
    });

    local = function (val) {
        return 'local: ' + val;
    };

    $tgt.html(env.render('test.nj', {
        'local': local
    }));
Run Code Online (Sandbox Code Playgroud)

并且呈现的HTML看起来像这样:

3                  // value

{ "a": 2 }         // object|pretty

func: undefined    // func

{}                 // args

local: undefined   // local
Run Code Online (Sandbox Code Playgroud)

所以,价值很好.该对象也可以工作,甚至在通过"漂亮"过滤器后看起来也很漂亮.

但是,传递给"func"的值在函数体中变为未定义,并且在函数内部使用arguments变量没有帮助.此外,将函数直接传递到模板上下文(本地)也不起作用.

过滤器(基本上只是函数)工作正常,但常规函数不会,无论它们是作为模板上下文的一部分传递还是作为全局传递.

一些可能有用的注意事项:

  • 我使用requirejs虽然(除了导入nunjucks本身)我试图从等式中消除它.

  • 这个例子使用了nunjucks v1.3.4.在调试过程中,我试图在v2.1中验证这种行为,但似乎v2.x可能已经破坏了requirejs的兼容性,我并不想并行处理两个问题.

  • 我正在使用grunt-nunjucks预编译我的模板,然后uglifying结果.我的Gruntfile的相关部分如下:

    module.exports = function (grunt) {
    'use strict';
    
    grunt.initConfig({
    
    pkg: grunt.file.readJSON('package.json'),
    
    nunjucks: {
        common: {
            baseDir: 'site/',
            src: [
                'site/core/**/*.nj'
            ],
            dest: 'application/static/js/common.js'
        },
    },
    
    uglify: {
        templates: {
            options: {
                preserveComments: false,
                mangle: true,
                compress: {
                    dead_code: true,
                    loops: true,
                    conditionals: true,
                    booleans: true,
                    unused: true,
                    if_return: true,
                    join_vars: true,
                    drop_console: true
                }
            },
            files: {
                'application/static/js/common.min.js': ['application/static/js/common.js'],
            }
        }
    },
    });
    
    grunt.loadNpmTasks('grunt-nunjucks');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    };
    
    Run Code Online (Sandbox Code Playgroud)

测试模板(如上所示)是编译成common.js的几个之一,然后使用上面的设置uglified到common.min.js.请注意,我尝试编译模板而不进行uglifying,但得到相同的结果.

这是非常基本的功能,所以如果这是一个错误,我希望在SE和问题日志中看到很多引用,但我几乎找不到.我想我错过了一些非常明显的东西,但似乎无法找到它.

有什么想法吗?

gar*_*ary 2

继续调试后,我最终通过以下测试设置将 uglification 和 requirejs 排除在外:

索引.html:

<html>
<head>
    <script src="nunjucks-slim.js"></script>
    <script src="common.js"></script>
</head>

<body>

    <script src="test.js"></script>
</body>

</html>
Run Code Online (Sandbox Code Playgroud)

我的模板,已预编译到 common.js 中:

<div>

<p>{{ value }}</p>

<p>{{ object|pretty }}</p>

<p>{{ func(4) }}</p>

<p>{{ func(x) }}</p>

<p>{{ args(4)|pretty }}</p>

<p>{{ local(4) }}</p>

<p>{{ local(x) }}</p>

</div>
Run Code Online (Sandbox Code Playgroud)

test.js 是执行模板的代码:

var env = new nunjucks.Environment(null),
    local;

env.addGlobal('value', 3);

env.addGlobal('object', {
    a: 2
});

env.addFilter('pretty', function (obj) {
    return JSON.stringify(obj, null, 2);
});

env.addGlobal('func', function (val) {
    return 'func: ' + val;
});

env.addGlobal('args', function () {
    return arguments;
});

local = function (val) {
    return 'local: ' + val;
};

console.log(env.render('core/root/test.nj', {
    'local': local,
    'x': 4
}));
Run Code Online (Sandbox Code Playgroud)

最后,演示问题的输出(带有添加的注释):

<div>

<p>3</p>    // value

<p>{
  "a": 2    // object|pretty
}</p>

<p>func: undefined</p>    // func(4)

<p>func: undefined</p>    // func(x)

<p>{}</p>    // args(4)|pretty

<p>local: undefined</p>    // local(4)

<p>local: undefined</p>    // local(x)

</div>
Run Code Online (Sandbox Code Playgroud)

我花了几个小时逐步浏览已编译的模板代码,试图找到问题(顺便说一句,这非常有用),然后我一脸震惊——因为我已经消除了,所以requirejs我可以再次尝试使用nunjucks v2.1.0.

单击几下后,我有了工作测试代码:

<div>

<p>3</p>

<p>{
  a: 2
}</p>

<p>func: 4</p>

<p>func: 4</p>

<p>{
  0: 4
}</p>

<p>local: 4</p>

<p>local: 4</p>

</div>
Run Code Online (Sandbox Code Playgroud)

因此,虽然很高兴找出并解决问题(使用 v1.3.4),但答案似乎是“升级到 nunjucks v2.1.0”