如何在Eleventy模板中用自定义Nunjucks过滤器过滤集合?
解决Nunjucks+Eleventy集合属性匹配过滤的问题
问题根源
你碰到的test not found: user_id错误,核心是搞混了Nunjucks的过滤器和测试(Test):
select是Nunjucks的内置筛选工具,它要的是测试名称,不是过滤器名称。你在.eleventy.js里加的是自定义过滤器,但select找的是同名测试,当然找不到。- 过滤器是用来转换数据的(比如格式化文本、修改数组结构),而测试是返回布尔值的判断逻辑——
select就是靠测试来判断集合项要不要保留的。
两种解决方法
方法一:给user_id写专属测试
如果只需要筛选user_id匹配的项,可以给Nunjucks注册自定义测试:
- 修改
.eleventy.js:
// .eleventy.js module.exports = function (eleventyConfig) { // 注册测试:判断项的user_id是否等于传入的目标值 eleventyConfig.addNunjucksTest("user_id", function(el, expectedId) { return el.user_id === expectedId; }); // 其他原有配置... };
- 模板里直接用
select调用:
// pages/index.njk {% set collection = [{user_id: 1, name: "one"}, {user_id: 2, name: "two"}] %} {% set filteredItems = collection | select("user_id", 1) %} {# 遍历输出筛选结果 #} {% for item in filteredItems %} {{ item.name }} {% endfor %}
方法二:写通用属性过滤过滤器(更灵活)
如果以后要筛选不同属性,写个通用过滤器更省事,不用每个属性都写测试:
- 修改
.eleventy.js:
// .eleventy.js module.exports = function (eleventyConfig) { // 通用过滤器:传入集合、属性名、目标值,返回匹配项 eleventyConfig.addFilter("filterByAttr", function(collection, attrName, targetValue) { return collection.filter(item => item[attrName] === targetValue); }); // 其他原有配置... };
- 模板里调用这个过滤器:
// pages/index.njk {% set collection = [{user_id: 1, name: "one"}, {user_id: 2, name: "two"}] %} {% set filteredItems = collection | filterByAttr("user_id", 1) %} {# 遍历输出筛选结果 #} {% for item in filteredItems %} {{ item.name }} {% endfor %}
额外说明
Nunjucks原生的selectattr确实只支持布尔属性(比如判断item.isPublished是不是true),没法直接匹配具体值,所以必须靠自定义逻辑来实现属性值匹配的筛选需求。
内容的提问来源于stack exchange,提问作者Goulven
相关产品推荐
相关产品推荐

