私は数か月間 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>
テンプレートをレンダリングするコード (これは、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
}));
レンダリングされた HTML は次のようになります。
3 // value
{ "a": 2 } // object|pretty
func: undefined // func
{} // args
local: undefined // local
したがって、値は問題ありません。オブジェクトも同様に機能し、「きれいな」フィルターを通過した後も見栄えがします。
ただし、「func」に渡される値は関数本体で未定義になり、関数内で引数変数を使用しても役に立ちません。さらに、関数をテンプレート コンテキスト (ローカル) に直接渡すこともできません。
フィルター (基本的には単なる関数) は正常に機能しますが、通常の関数は、テンプレート コンテキストの一部として渡されるか、グローバルとして渡されるかに関係なく機能しません。
役立つかもしれないいくつかのメモ:
私はrequirejsを使用していますが(nunjucks自体のインポートを除く)、方程式から排除しようとしました。
この例では、nunjucks v1.3.4 を使用しています。デバッグの過程で、v2.1 でこの動作を確認しようとしましたが、v2.x では requirejs の互換性が壊れている可能性があり、2 つの問題に並行して取り組みたくありませんでした。
grunt-nunjucks を使用してテンプレートをプリコンパイルし、結果を醜くしています。私の 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'); };
テスト テンプレート (上に表示) は、common.js にコンパイルされ、上記の設定を使用して common.min.js に醜化されたいくつかのテンプレートの 1 つです。醜くすることなくテンプレートをコンパイルしようとしましたが、同じ結果が得られたことに注意してください。
これは非常に基本的な機能であるため、これがバグであるとすれば、SE やイシュー ログで多くの参照が見られると思いますが、ほとんど見つかりませんでした。本当に明白なものが欠けていると思いますが、それを見つけることができないようです。
何かご意見は?