问题描述
所以我有一些来自 JSON API 的书籍数据。对于 API 中的一些项目,我在 11ty 中创建了一个页面。我正在尝试从 API 中列出项目,并检查每个项目的 slug
字段是否与我的本地页面集合中的 fileSlug
匹配。如果是这样,那么我可以输出到内容页面的链接;否则,只需从 API 输出书名。
这是我在 Nunjucks 所拥有的:
{# Loop through book entries in API #}
{% for apiBook in booksApi %}
{{ apiBook.title }}:
{# Loop through my local book pages collection #}
{% for localBook in collections.books %}
{# Check if any slugs in the local collection match slugs in API #}
{% if localBook.fileSlug == apiBook.slug %}
Item exists locally.
{% else %}
Item only exists on API.
{% endif %}
{% endfor %}
<br>
{% endfor %}
我不明白的是,这对于 API 中的每个项目返回两次...对于 11ty 中没有相应页面的项目,它返回 {{1} }.对于有相应页面的项目,它返回 Item only exists on API. Item only exists on API.
。
知道为什么 Item exists locally. Item only exists on API.
语句总是返回 true 吗?
在 else
中创建自定义过滤器:
.eleventy.js
解决方法
问题是嵌套循环。您有一个 API 书籍循环,另一个循环用于每一本本地书籍,因此您的代码针对 API 中的每一本书运行所有本地书籍。这就是您看到额外输出的原因,总行数将是 API 图书的数量乘以本地图书的数量(例如 2 * 2 = 4
或 2 * 3 = 6
)。
在 Nunjucks 中,您想做的事情并非微不足道。通常,您可以使用 in
关键字来检查一本书是否属于您的收藏,但当您需要比较对象属性时,这不起作用。
相反,我建议将您的逻辑移至 JavaScript,在那里您可以使用 Array.prototype.find 和类似方法更轻松地进行比较。例如,您的 apiBooks 变量是否来自数据文件?在这种情况下,您可以在那里解析列表并添加对本地图书文件的引用(如果可用)。另一种方法是添加一个 custom filter,它将一个 apiBook 对象和本地图书集合作为参数并返回匹配的图书(如果存在)。
// .eleventy.js
eleventyConfig.addFilter('getLocalBook',(bookData,localBooks) => {
// find matching book and return it,or return null
} );
然后你可以这样使用它:
{% for apiBook in booksApi %}
{% set localBook = apiBook | getLocalBook(collections.books) %}
{% if localBook %}
Item exists locally.
{% else %}
Item only exists on API.
{% endif %}
{% endfor %}