如果一个数组包含另一个带有 Eleventy 的数组值,如何检查 Nunjucks

How to check in Nunjucks if an array contains another array value with Eleventy

所以我有一些来自 JSON API 的书籍数据。对于 API 中的一些项目,我在 11ty 中创建了一个页面。我正在尝试列出 API 中的项目,并检查每个项目的 slug 字段是否与我的本地页面集合中的 fileSlug 相匹配。如果是这样,那么我可以向内容页面输出一个link;否则,只需从 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 %}

我不明白的是,returns 两次 对于 API 中的每个项目...在 11ty 中没有相应的页面,它 returns Item only exists on API. Item only exists on API.。对于确实有相应页面的项目,它 returns Item exists locally. Item only exists on API..

知道为什么 else 语句总是 return 为真吗?


.eleventy.js 中创建自定义过滤器:

eleventyConfig.addFilter("matchLocalBook", (apiBook, localBooks) => {
  return localBooks.find(element => element.fileSlug === apiBook.slug);
});

问题是嵌套循环。对于 API 本书有一个循环,对于每本本地书籍都有一个循环,因此对于来自API。这就是您看到额外输出的原因,总行数将是 API 本书的数量乘以本地书籍的数量(例如 2 * 2 = 42 * 3 = 6)。

你想做的事情在 Nunjucks 中并不简单。通常,您可以使用 in 关键字来检查一本书是否属于您的 collection,但是当您需要比较 object 属性时,这不起作用。

相反,我建议将您的逻辑移动到 JavaScript,您可以使用 Array.prototype.find and similar methods. For example, does your apiBooks variable come from a data file? In that case, you could parse the list there and add the reference to the local book file, if available. Another method would be to add a custom filter 更轻松地进行比较,它需要一个 apiBook object 和本地书籍 collection 作为参数和 returns 匹配的书,如果存在的话。

// .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 %}