如何在 Eleventy 中创建标签集合和类别集合
How to create a Tags collection and a Categories collection in Eleventy
我的 .eleventy.js
文件中有以下两段代码
// Tags
eleventyConfig.addCollection('tagList', collection => {
const tagsSet = new Set();
collection.getAll().forEach(item => {
if (!item.data.tags) return;
item.data.tags.filter(tag => !['posts', 'all'].includes(tag)).forEach(tag => tagsSet.add(tag));
});
return Array.from(tagsSet).sort();
});
// Categories
eleventyConfig.addCollection('categoryList', collection => {
let catSet = new Set();
collection.getAll().forEach(item => {
if (!item.data.categories) return;
item.data.categories.filter(cat => !['posts', 'all'].includes(cat)).forEach(cat => catSet.add(cat));
});
return Array.from(catSet).sort();
});
在我的帖子里我有
---
layout: post
title: 'Whatever'
date: '2021-10-12'
permalink: '{{ title | slug }}/index.html'
categories:
- code
tags:
- javascript
- angular
---
我正在使用这样的模板为每个标签自动生成页面(以及类似的类别页面)。
---
layout: page
eleventyComputed:
title: All posts tagged '{{ tag }}'
permalink: /tags/{{ tag }}/
pagination:
data: collections
size: 1
alias: tag
filter:
- all
- nav
- post
- posts
- tagList
addAllPagesToCollections: true
permalink: /tags/{{ tag }}/
headerButton:
url: '/blog/'
text: All posts
---
<ul class="unstyled">
{%- for post in collections[tag].reverse() -%}
{%- if not post.data.draft -%}
<li>{% include 'post-listing.njk' %}</li>
{%- endif -%}
{%- endfor -%}
</ul>
对于标签,一切正常。我生成了正确的页面,即 /tags/javascript
但对于类别,它根据标签而不是类别生成页面。所以我最终得到的不是 /categories/code
/categories/javascript
我假设问题出在我的 eleventyConfig.addCollection('categoryList')
函数上,但我不知道为什么。
您的问题可能出在模板的分页中。您在 collections
object 上分页,这是一个对象映射标签(一个特殊的 11ty 前端属性)到具有该标签的页面。
由于您正在创建标签和类别列表作为集合项,因此您需要对该集合进行分页。
---
# ...
pagination:
data: collections.tagList # (or collections.categoryList)
size: 1
alias: tag
# ...
---
这可能会造成问题,因为您正在访问模板中的帖子本身,因此您需要一种方法将 tag/category 映射回帖子列表。您可以通过将集合更改为 Object
而不是 Array
.
来解决此问题
// Tags
eleventyConfig.addCollection('tagList', collection => {
const tagsSet = {};
collection.getAll().forEach(item => {
if (!item.data.tags) return;
item.data.tags.filter(
tag => !['posts', 'all'].includes(tag)
).forEach(
tag => {
if (!tagsSet[tag]) { tagsSet[tag] = []; }
tagsSet[tag].push(item)
}
);
});
return tagsSet;
});
// Categories
eleventyConfig.addCollection('categoryList', collection => {
let catSet = {};
collection.getAll().forEach(item => {
if (!item.data.categories) return;
item.data.categories.filter(
cat => !['posts', 'all'].includes(cat)
).forEach(
cat => {
if (!catSet[cat]) { catSet[cat] = []; }
catSet[cat].push(item)
}
);
});
return catSet;
});
现在,当您想要访问帖子时,您可以索引到 collections.tagList
(或 collections.categoryList
)。
{%- for post in collections.tagList[tag] | reverse -%}
您上面建议的一切都奏效了。我现在为标签和类别生成了单独的页面,非常感谢。
我现在遇到的问题是,在我的博客页面上,我以前有一个像这样输出的标签列表
<div class="tags tags--buttons">
{%- for tag in collections.tagList -%}
<a href="/tags/{{tag}}">{{tag}}</a>
{%- endfor -%}
</div>
这不再输出任何内容,因为集合不再是数组。
我更新到
<div class="tags tags--buttons">
{%- for tag, val in collections.tagList -%}
<a href="/tags/{{tag}}">{{tag}}</a>
{%- endfor -%}
</div>
这适用于标签,但不适用于集合(使用 collections.categoryList
)
此外,标签不再按字母顺序排列
有什么建议吗?
更新:
输出类别的代码是
{%- for cat, val in collections.categoryList | dictsort -%}
{%- if cat !== "posts" -%}
<a href="/categories/{{cat}}">{{cat}}</a>
{%- endif -%}
{%- endfor -%}
这不会给出任何错误,但也没有输出。
如果我向其中添加 | dictsort
,则会收到错误 Template render error: dictsort filter: val must be an object
我的 .eleventy.js
文件中有以下两段代码
// Tags
eleventyConfig.addCollection('tagList', collection => {
const tagsSet = new Set();
collection.getAll().forEach(item => {
if (!item.data.tags) return;
item.data.tags.filter(tag => !['posts', 'all'].includes(tag)).forEach(tag => tagsSet.add(tag));
});
return Array.from(tagsSet).sort();
});
// Categories
eleventyConfig.addCollection('categoryList', collection => {
let catSet = new Set();
collection.getAll().forEach(item => {
if (!item.data.categories) return;
item.data.categories.filter(cat => !['posts', 'all'].includes(cat)).forEach(cat => catSet.add(cat));
});
return Array.from(catSet).sort();
});
在我的帖子里我有
---
layout: post
title: 'Whatever'
date: '2021-10-12'
permalink: '{{ title | slug }}/index.html'
categories:
- code
tags:
- javascript
- angular
---
我正在使用这样的模板为每个标签自动生成页面(以及类似的类别页面)。
---
layout: page
eleventyComputed:
title: All posts tagged '{{ tag }}'
permalink: /tags/{{ tag }}/
pagination:
data: collections
size: 1
alias: tag
filter:
- all
- nav
- post
- posts
- tagList
addAllPagesToCollections: true
permalink: /tags/{{ tag }}/
headerButton:
url: '/blog/'
text: All posts
---
<ul class="unstyled">
{%- for post in collections[tag].reverse() -%}
{%- if not post.data.draft -%}
<li>{% include 'post-listing.njk' %}</li>
{%- endif -%}
{%- endfor -%}
</ul>
对于标签,一切正常。我生成了正确的页面,即 /tags/javascript
但对于类别,它根据标签而不是类别生成页面。所以我最终得到的不是 /categories/code
/categories/javascript
我假设问题出在我的 eleventyConfig.addCollection('categoryList')
函数上,但我不知道为什么。
您的问题可能出在模板的分页中。您在 collections
object 上分页,这是一个对象映射标签(一个特殊的 11ty 前端属性)到具有该标签的页面。
由于您正在创建标签和类别列表作为集合项,因此您需要对该集合进行分页。
---
# ...
pagination:
data: collections.tagList # (or collections.categoryList)
size: 1
alias: tag
# ...
---
这可能会造成问题,因为您正在访问模板中的帖子本身,因此您需要一种方法将 tag/category 映射回帖子列表。您可以通过将集合更改为 Object
而不是 Array
.
// Tags
eleventyConfig.addCollection('tagList', collection => {
const tagsSet = {};
collection.getAll().forEach(item => {
if (!item.data.tags) return;
item.data.tags.filter(
tag => !['posts', 'all'].includes(tag)
).forEach(
tag => {
if (!tagsSet[tag]) { tagsSet[tag] = []; }
tagsSet[tag].push(item)
}
);
});
return tagsSet;
});
// Categories
eleventyConfig.addCollection('categoryList', collection => {
let catSet = {};
collection.getAll().forEach(item => {
if (!item.data.categories) return;
item.data.categories.filter(
cat => !['posts', 'all'].includes(cat)
).forEach(
cat => {
if (!catSet[cat]) { catSet[cat] = []; }
catSet[cat].push(item)
}
);
});
return catSet;
});
现在,当您想要访问帖子时,您可以索引到 collections.tagList
(或 collections.categoryList
)。
{%- for post in collections.tagList[tag] | reverse -%}
您上面建议的一切都奏效了。我现在为标签和类别生成了单独的页面,非常感谢。
我现在遇到的问题是,在我的博客页面上,我以前有一个像这样输出的标签列表
<div class="tags tags--buttons">
{%- for tag in collections.tagList -%}
<a href="/tags/{{tag}}">{{tag}}</a>
{%- endfor -%}
</div>
这不再输出任何内容,因为集合不再是数组。
我更新到
<div class="tags tags--buttons">
{%- for tag, val in collections.tagList -%}
<a href="/tags/{{tag}}">{{tag}}</a>
{%- endfor -%}
</div>
这适用于标签,但不适用于集合(使用 collections.categoryList
)
此外,标签不再按字母顺序排列
有什么建议吗?
更新:
输出类别的代码是
{%- for cat, val in collections.categoryList | dictsort -%}
{%- if cat !== "posts" -%}
<a href="/categories/{{cat}}">{{cat}}</a>
{%- endif -%}
{%- endfor -%}
这不会给出任何错误,但也没有输出。
如果我向其中添加 | dictsort
,则会收到错误 Template render error: dictsort filter: val must be an object