导入一个Nunjucks宏?

时间:2018-09-10 02:53:25

标签: javascript html node.js nunjucks

我有一个脚本,可以渲染如下所示的nunjucks contact.html模板:

    let fs = require('fs');
    let nj = require('nunjucks');
    var contact = fs.readFileSync('./src/contact.html','utf8');
    nj.configure('src');
    let result = nj.render('contact.html');
    console.log(result);

它可以正常工作并记录正确的result

我现在尝试添加一个宏,并将定义放入templates/forms.njk文件中。然后,我尝试像这样从contacts.html加载它:

{% import "templates/forms.njk" as forms %}

{% set title = 'Contact' %}
{% extends '_layout.html' %}
{% block content %}
<h1>Test Template</h1>
{% endblock %}

现在results的记录为null,但是如果我删除了宏,导入将记录呈现的联系人模板。有想法吗?

src目录布局如下:

├── contact.html
├── index.html
├── _layout.html
└── templates
    └── forms.njk

1 个答案:

答案 0 :(得分:1)

第二个宏缺少结束语句function foo(a: string, b: string, c: number): string { return 'Yay!' } // Attempt 1: // Taken from // https://github.com/facebook/flow/issues/4672#issuecomment-377649789 declare function arguments<A>((A) => any): [A] declare function arguments<A, B>((A, B) => any): [A, B] declare function arguments<A, B, C>((A, B, C) => any): [A, B, C] declare function arguments<A, B, C, D>((A, B, C, D) => any): [A, B, C, D] type Arguments<T> = $Call<typeof arguments, T> function hof1 <T: Function> (t: T): (...Arguments<T>) => void { return (...args) => undefined; } const augmentedFn = hof1(foo)("This", "works", 2); // const augmentedFn2 = hof1(foo)("this", "should't", "work"); // const augmentedFn2 = hof1(foo)("Also", "check", 2, "number of args"); // Attempt 2: using array of mixed. // This one doesn't seem to have limit to the arguments you can provide, // but it doesn't seem to fail when extra args are passed. // Notice that the return type is specified in the function signature function hof2 <T: Array<mixed>>(func: (...T) => any): (...args: T) => any { return (...args) => null; } hof2(foo)("2", "2", 1); // hof2(foo)(1, "this fails correctly", 1); hof2(foo)("2", "2", 1, "This one has extra arg, but this method can't limit them"); // If we define the generic return type in the returned function, flow breaks function hof2broken <T: Array<mixed>>(func: (...T) => any) { return (...args: T) => null; } // hof2broken(foo)("This should work", "but fails with a cryptic message", 1); // Attempt 3, using generics to capture the tuple values. // It requires us to declare one generic for each arg in any function // that uses them. Notice that I have to redeclare all the A, B, C and D generic // types just to pass them to the tuple type. type genericTuple<A, B, C, D> = [A] | [A, B] | [A, B, C] | [A, B, C, D] function hof3<A, B, C, D, T: genericTuple<A, B, C, D>>(func: (...T) => any): (...args: T) => any { return (...args) => null; } hof3(foo)("This", "works", 2); // hof3(foo)("this", "should't", "work"); hof3(foo)("Also", "fails", 2, "to check the argument's length"); // hof3(foo)("Also", "fails", 2, "to check the argument's length", "until it exceeds the number of possible args"); // Attempt 4 // It seems to be possible to ommit the generics by using tuples of 'any' // This seems to have the same issues of not checking for extra unwanted args type anyTuple = [any] | [any, any] | [any, any, any] | [any, any, any, any] function hof4<T: anyTuple>(func: (...T) => any): (...args: T) => any { return (...args) => null; } hof4(foo)("This", "works", 2); // hof4(foo)("this", "should't", "work"); hof4(foo)("Also", "fails", 2, "to check the argument's length"); // Attempt 5: // Trying to extract the type calculated in // https://github.com/facebook/flow/issues/4672#issuecomment-377649789 // without getting redeclaration warnings // This works in the 'try' console, but doesn't in the 0.80.0 version // in Mac OS, so I can't stick with it // I think that this working on the 'try' console is probably a bug type ArgsFrom<T> = $Call< (<A>((A) => any) => [A]) & (<A, B>((A, B) => any) => [A, B]) & (<A, B, C>((A, B, C) => any) => [A, B, C]) & (<A, B, C, D>((A, B, C, D) => any) => [A, B, C, D]), T> // type Arguments2<T> = $Call<argtest, T> function hof5 <T: Function> (t: T): (...ArgsFrom<T>) => void { return (...args) => undefined; } let testVar = hof5(foo); hof5(foo)("This", "works", 2); // hof5(foo)("this", "should't", "work"); // hof5(foo)("Correctly", "fails", 2, "when there are extra args"); // Attempt 6: I read somewhere that overloading is supported // on interfaces, so I gave it a try. It seems to work and I will stick with it. type Arguments3 = { <A>((A) => any): [A], <A, B>((A, B) => any): [A, B], <A, B, C>((A, B, C) => any): [A, B, C], <A, B, C, D>((A, B, C) => any): [A, B, C, D], } function hof6 <T: Function> (t: T): (...$Call<Arguments3, T>) => void { return (...args) => undefined; } hof6(foo); hof6((a: string, b: boolean) => null)("Also works", true); hof6(foo)("This", "works", 2); hof6(foo)("this", "should't", "work"); hof6(foo)("Correctly", "fails", 2, "when there are extra args"); // Yay! Works and kind of makes sense Sample project here if anyone wants to play with the setup

Note还更新了{% endmacro %}调用以记录错误。