跳转到导航 跳转到主要内容
CNB版本
社区版
cnb.cool
国外版
cnb.build
2025/12/14

Nunjucks

本页大纲
Eleventy 简称 文件扩展名 npm 包
njk .html nunjucks
Eleventy 版本 nunjucks 版本
@11ty/eleventy@0.x nunjucks@3.x
@11ty/eleventy@1.x nunjucks@3.x
@11ty/eleventy@2.x nunjucks@3.x
@11ty/eleventy@3.x nunjucks@3.x

您可以覆盖 .html 文件的模板引擎。更多信息请阅读更改模板的渲染引擎

Nunjucks 环境选项

我们对所有环境选项使用 Nunjucks 默认值(在 Nunjucks 文档的 configure 部分显示)。

可选:使用您的 Nunjucks 环境选项

建议使用配置 API 来覆盖默认的 Nunjucks 选项。

eleventy.config.js
export default function (eleventyConfig) {
eleventyConfig.setNunjucksEnvironmentOptions({
throwOnUndefined: true,
autoescape: false, // 警告:不要这样做!
});
};
module.exports = function (eleventyConfig) {
eleventyConfig.setNunjucksEnvironmentOptions({
throwOnUndefined: true,
autoescape: false, // 警告:不要这样做!
});
};

高级:使用你的 Nunjucks 环境

虽然使用上面特定于选项的 API 方法(Eleventy 1.0 中的新功能!)更受欢迎且更简单——但作为高级使用的转义机制,您可以使用配置 API 传入自己的 Nunjucks Environment 实例。

WARNING
Not compatible with setNunjucksEnvironmentOptions above—this method will override any configuration set there.
eleventy.config.js
import Nunjucks from "nunjucks";

export default function (eleventyConfig) {
let nunjucksEnvironment = new Nunjucks.Environment(
new Nunjucks.FileSystemLoader("\_includes")
);

    eleventyConfig.setLibrary("njk", nunjucksEnvironment);

};
const Nunjucks = require("nunjucks");

module.exports = function (eleventyConfig) {
let nunjucksEnvironment = new Nunjucks.Environment(
new Nunjucks.FileSystemLoader("\_includes")
);

    eleventyConfig.setLibrary("njk", nunjucksEnvironment);

};

支持的功能

功能 语法
✅ 包含 {% include 'included.html' %}_includes/included.html 中查找。文件名必须用引号括起来。不处理 include 文件中的前置内容。
✅ 包含(相对路径) 相对路径使用 ./(模板的目录)或 ../(模板的父目录)。

示例:{% include './included.html' %} 在模板的当前目录中查找 included.html。不处理 include 文件中的前置内容。
✅ 扩展 {% extends 'base.html' %}_includes/base.html 中查找。不处理 include 文件中的前置内容。
✅ 扩展(相对路径) 相对路径使用 ./(模板的目录)或 ../(模板的父目录)。

示例:{% extends './base.html' %} 在模板的当前目录中查找 base.html。不处理 include 文件中的前置内容。
✅ 导入 {% import 'macros.html' %}_includes/macros.html 中查找。不处理 include 文件中的前置内容。
✅ 导入(相对路径) 相对路径使用 ./(模板的目录)或 ../(模板的父目录):
{% import './macros.html' %} 在模板的当前目录中查找 macros.html。不处理 include 文件中的前置内容。
✅ 过滤器 {% name | filterName %} 阅读更多关于过滤器的信息。
通用过滤器 {% name | filterName %} 阅读更多关于过滤器的信息。
自定义标签 {% uppercase name %} 阅读更多关于自定义标签的信息。
短代码 {% uppercase name %} 阅读更多关于短代码的信息。

过滤器

过滤器用于转换或修改内容。您可以添加 Nunjucks 特定的过滤器,但您可能想添加通用过滤器

阅读更多关于 Nunjucks 过滤器语法的信息。

eleventy.config.js
export default function(eleventyConfig) {
// Nunjucks 过滤器
eleventyConfig.addNunjucksFilter("myNjkFilter", function(value) { /_ … _/ });

// Nunjucks 异步过滤器(请阅读下文)
eleventyConfig.addNunjucksAsyncFilter("myAsyncNjkFilter", function(value, callback) { /_ … _/ });

// 通用过滤器(添加到 Liquid、Nunjucks 和 11ty.js)
eleventyConfig.addFilter("myFilter", function(value) { /_ … _/ });
};
module.exports = function(eleventyConfig) {
// Nunjucks 过滤器
eleventyConfig.addNunjucksFilter("myNjkFilter", function(value) { /_ … _/ });

// Nunjucks 异步过滤器(请阅读下文)
eleventyConfig.addNunjucksAsyncFilter("myAsyncNjkFilter", function(value, callback) { /_ … _/ });

// 通用过滤器(添加到 Liquid、Nunjucks 和 11ty.js)
eleventyConfig.addFilter("myFilter", function(value) { /_ … _/ });
};

使用方法

<h1>{{ myVariable | myFilter }}</h1>

多个过滤器参数

eleventy.config.js
export default function (eleventyConfig) {
// Nunjucks 过滤器
eleventyConfig.addNunjucksFilter(
"concatThreeStrings",
function (arg1, arg2, arg3) {
return arg1 + arg2 + arg3;
}
);
};
module.exports = function (eleventyConfig) {
// Nunjucks 过滤器
eleventyConfig.addNunjucksFilter(
"concatThreeStrings",
function (arg1, arg2, arg3) {
return arg1 + arg2 + arg3;
}
);
};
<h1>{{ "first" | concatThreeThings("second", "third") }}</h1>

异步 Nunjucks 过滤器

默认情况下,几乎所有模板引擎都是同步的。Nunjucks 支持一些异步行为,比如过滤器。其工作原理如下:

eleventy.config.js
export default function (eleventyConfig) {
eleventyConfig.addNunjucksAsyncFilter(
"myAsyncFilter",
function (value, callback) {
setTimeout(function () {
callback(null, "My Result");
}, 100);
}
);
};
module.exports = function (eleventyConfig) {
eleventyConfig.addNunjucksAsyncFilter(
"myAsyncFilter",
function (value, callback) {
setTimeout(function () {
callback(null, "My Result");
}, 100);
}
);
};

这里的最后一个参数是回调函数,其第一个参数是错误对象,第二个是结果数据。像使用任何其他过滤器一样使用此过滤器:{{ myValue | myAsyncFilter }}

这是一个带有 2 个参数的 Nunjucks 示例:

eleventy.config.js
export default function (eleventyConfig) {
eleventyConfig.addNunjucksAsyncFilter(
"myAsyncFilter",
function (value1, value2, callback) {
setTimeout(function () {
callback(null, "My Result");
}, 100);
}
);
};
module.exports = function (eleventyConfig) {
eleventyConfig.addNunjucksAsyncFilter(
"myAsyncFilter",
function (value1, value2, callback) {
setTimeout(function () {
callback(null, "My Result");
}, 100);
}
);
};

在 Nunjucks 中,多参数过滤器的调用方式如下:{{ myValue1 | myAsyncFilter(myValue2) }}

短代码

短代码是可重用的内容片段。您可以添加 Nunjucks 特定的短代码,但可能更容易添加通用短代码

单个短代码

eleventy.config.js
export default function(eleventyConfig) {
// Nunjucks 短代码
eleventyConfig.addNunjucksShortcode("user", function(name, twitterUsername) { /_ … _/ });

// 通用短代码(添加到 Liquid、Nunjucks、11ty.js)
eleventyConfig.addShortcode("user", function(name, twitterUsername) {
return `<div class="user">

<div class="user_name">${name}</div>
<div class="user_twitter">@${twitterUsername}</div>
</div>`;
  });
};
module.exports = function(eleventyConfig) {
// Nunjucks 短代码
eleventyConfig.addNunjucksShortcode("user", function(name, twitterUsername) { /_ … _/ });

// 通用短代码(添加到 Liquid、Nunjucks、11ty.js)
eleventyConfig.addShortcode("user", function(name, twitterUsername) {
return `<div class="user">

<div class="user_name">${name}</div>
<div class="user_twitter">@${twitterUsername}</div>
</div>`;
  });
};

Nunjucks 模板使用方法

{% user "Zach Leatherman", "zachleat" %}

输出

<div class="user">
	<div class="user_name">Zach Leatherman</div>
	<div class="user_twitter">@zachleat</div>
</div>

成对短代码

eleventy.config.js
export default function(eleventyConfig) {
// Nunjucks 短代码
eleventyConfig.addPairedNunjucksShortcode("user", function(bioContent, name, twitterUsername) { /_ … _/ });

// 通用短代码(添加到 Liquid、Nunjucks、11ty.js)
eleventyConfig.addPairedShortcode("user", function(bioContent, name, twitterUsername) {
return `<div class="user">

<div class="user_name">${name}</div>
<div class="user_twitter">@${twitterUsername}</div>
<div class="user_bio">${bioContent}</div>
</div>`;
  });
};
module.exports = function(eleventyConfig) {
// Nunjucks 短代码
eleventyConfig.addPairedNunjucksShortcode("user", function(bioContent, name, twitterUsername) { /_ … _/ });

// 通用短代码(添加到 Liquid、Nunjucks、11ty.js)
eleventyConfig.addPairedShortcode("user", function(bioContent, name, twitterUsername) {
return `<div class="user">

<div class="user_name">${name}</div>
<div class="user_twitter">@${twitterUsername}</div>
<div class="user_bio">${bioContent}</div>
</div>`;
  });
};

Nunjucks 使用方法

注意,您可以在 {% user %} 短代码内放置任何 Nunjucks 标签或内容!是的,甚至其他短代码也可以!

{% user "Zach Leatherman", "zachleat" %}
  Zach likes to take long walks on Nebraska beaches.
{% enduser %}
输出
<div class="user">
	<div class="user_name">Zach Leatherman</div>
	<div class="user_twitter">@zachleat</div>
	<div class="user_bio">Zach likes to take long walks on Nebraska beaches.</div>
</div>

短代码命名参数语法(仅限 Nunjucks)

创建一个参数对象传递给短代码。

eleventy.config.js
export default function(eleventyConfig) {
// Nunjucks 短代码
eleventyConfig.addNunjucksShortcode("user", function (user) {
return `<div class="user">

<div class="user_name">${user.name}</div>
${user.twitter ? `<div class="user_twitter">@${user.twitter}</div>` : ""}
</div>`;
	});
};
module.exports = function(eleventyConfig) {
// Nunjucks 短代码
eleventyConfig.addNunjucksShortcode("user", function (user) {
return `<div class="user">

<div class="user_name">${user.name}</div>
${user.twitter ? `<div class="user_twitter">@${user.twitter}</div>` : ""}
</div>`;
	});
};

Nunjucks 使用方法

参数的顺序无关紧要。

{% user name="Zach Leatherman", twitter="zachleat" %}
{% user twitter="zachleat", name="Zach Leatherman" %}
输出
<div class="user">
	<div class="user_name">Zach Leatherman</div>
	<div class="user_twitter">@zachleat</div>
</div>

Nunjucks 使用方法

重要的是,此语法意味着任何参数都可以是可选的(无需传入一堆 null, null, null 来维持顺序)。

{% user name="Zach Leatherman" %}
输出
<div class="user">
	<div class="user_name">Zach Leatherman</div>
</div>

异步短代码

请注意,这里添加异步短代码的配置方法与其同步对应方法不同。这只是另一个温和的提醒,这些 API 方法相当冗长,可能更容易添加通用短代码

eleventy.config.js
export default function (eleventyConfig) {
eleventyConfig.addNunjucksAsyncShortcode(
"user",
async function (name, twitterUsername) {
return await fetchAThing();
}
);

    eleventyConfig.addPairedNunjucksAsyncShortcode(
    	"user2",
    	async function (content, name, twitterUsername) {
    		return await fetchAThing();
    	}
    );

};
module.exports = function (eleventyConfig) {
eleventyConfig.addNunjucksAsyncShortcode(
"user",
async function (name, twitterUsername) {
return await fetchAThing();
}
);

    eleventyConfig.addPairedNunjucksAsyncShortcode(
    	"user2",
    	async function (content, name, twitterUsername) {
    		return await fetchAThing();
    	}
    );

};

Nunjucks 使用方法

这与同步 Nunjucks 使用方法相同。

{% user "Zach Leatherman", "zachleat" %}

{% user2 "Zach Leatherman", "zachleat" %}
  Zach likes to take long walks on Nebraska beaches.
{% enduser2 %}

警告:宏不支持异步

根据 Nunjucks 文档,Nunjucks 宏不支持异步

如果您使用异步 API,请注意您不能在宏内部执行任何异步操作。这是因为宏像普通函数一样被调用。将来我们可能会有一种方法异步调用函数。如果您现在这样做,行为是未定义的。

警告:set 不支持异步

这是一个常见陷阱

Nunjucks 的 {% set %} 标签 不能用于捕获异步内容(例如异步短代码)。

从 Eleventy v1.0.0 开始,Eleventy 提供了 {% setAsync %} 标签来解决此限制。值得注意的是,与 set 相反,setAsync 的第一个参数是字符串。

{% setAsync "myVariableName" %}
{% myAsyncShortcode %}
{% endsetAsync %}

<!-- 现在使用该变量 -->
{{ myVariableName }}

访问 Eleventy 提供的数据

您可以在过滤器和短代码中访问 pageeleventyctxenv。阅读更多关于短代码过滤器文档的信息。

通用全局变量

Nunjucks 提供了一种自定义方式来添加全局变量到模板中。这些可以是任意 JavaScript:函数、变量等。请注意,这不支持异步(Nunjucks 不支持在模板内部使用 await)。

eleventy.config.js
export default function (eleventyConfig) {
eleventyConfig.addNunjucksGlobal("fortythree", 43);
};
module.exports = function (eleventyConfig) {
eleventyConfig.addNunjucksGlobal("fortythree", 43);
};
{{ fortythree }}
eleventy.config.js
export default function (eleventyConfig) {
eleventyConfig.addNunjucksGlobal("fortytwo", function () {
return 42;
});
};
module.exports = function (eleventyConfig) {
eleventyConfig.addNunjucksGlobal("fortytwo", function () {
return 42;
});
};
{{ fortytwo() }}

阅读更多关于 Nunjucks 文档相关讨论 Eleventy Issue #1060的信息。


其他页面在 Template Languages