如何在Eleventy中实现标签集合的多级分页?
解决Eleventy中标签分页(多级分页)的可行方案
Eleventy原生不支持你尝试的嵌套pagination配置,要实现每个标签下的文章分页,得通过自定义集合+手动分页切片的方式来完成,以下是两种可行方案:
方案一:自定义集合配合模板手动分页(推荐)
1. 先在.eleventy.js中生成标签-文章分组集合
module.exports = function(eleventyConfig) { eleventyConfig.addCollection("tagWithPosts", function(collectionApi) { const tagGroup = {}; // 遍历所有文章,按标签分组 collectionApi.getAll().forEach(post => { if (post.data.tags) { post.data.tags.forEach(tag => { if (!tagGroup[tag]) tagGroup[tag] = []; tagGroup[tag].push(post); }); } }); // 转换为分页可用的数组结构:每个元素含标签名和对应文章列表 return Object.entries(tagGroup).map(([tag, posts]) => ({ tag, posts: posts.sort((a, b) => b.date - a.date) // 按日期倒序排序 })); }); };
2. 创建标签分页模板(如tag-pagination.njk)
--- pagination: data: collections.tagWithPosts size: 1 alias: currentTagGroup permalink: "tags/{{ currentTagGroup.tag }}/page/{{ pagination.pageNumber + 1 }}/" --- {% set postsPerPage = 10 %} {% set totalPosts = currentTagGroup.posts.length %} {% set totalPages = (totalPosts / postsPerPage) | round(0, 'ceil') %} {% set currentPage = pagination.pageNumber + 1 %} {% set startIndex = (currentPage - 1) * postsPerPage %} {% set paginatedPosts = currentTagGroup.posts.slice(startIndex, startIndex + postsPerPage) %} <h1>标签:{{ currentTagGroup.tag }} 第{{ currentPage }}页</h1> <ul> {% for post in paginatedPosts %} <li><a href="{{ post.url }}">{{ post.data.title }}</a></li> {% endfor %} </ul> <!-- 分页导航 --> {% if totalPages > 1 %} <div class="pagination-bar"> {% if currentPage > 1 %} <a href="/tags/{{ currentTagGroup.tag }}/page/{{ currentPage - 1 }}/">上一页</a> {% endif %} {% for pageNum in 1..totalPages %} <a href="/tags/{{ currentTagGroup.tag }}/page/{{ pageNum }}/" {% if pageNum == currentPage %}class="active"{% endif %}>{{ pageNum }}</a> {% endfor %} {% if currentPage < totalPages %} <a href="/tags/{{ currentTagGroup.tag }}/page/{{ currentPage + 1 }}/">下一页</a> {% endif %} </div> {% endif %}
该模板会自动为每个标签的每一页生成URL(如tags/javascript/page/1/、tags/javascript/page/2/),同时处理文章切片和分页导航逻辑。
方案二:数据文件配合模板分页
1. 创建_data/tagData.js生成标签分组数据
module.exports = function() { const fs = require('fs'); const path = require('path'); const postDir = './src/posts'; // 你的文章存储目录 const tagMap = {}; fs.readdirSync(postDir).forEach(file => { if (file.endsWith('.md')) { const content = fs.readFileSync(path.join(postDir, file), 'utf8'); // 提取YAML frontmatter中的tags字段 const frontmatter = content.match(/^---\s*([\s\S]*?)\s*---/); if (frontmatter) { const tagsMatch = frontmatter[1].match(/tags:\s*\[([^\]]+)\]/); if (tagsMatch) { const tags = tagsMatch[1].split(',').map(t => t.trim().replace(/['"]/g, '')); tags.forEach(tag => { if (!tagMap[tag]) tagMap[tag] = []; tagMap[tag].push(file); }); } } } }); return Object.entries(tagMap).map(([tag, files]) => ({ tag, files })); };
2. 模板中基于tagData分页并关联文章
模板逻辑和方案一类似,只是需要通过文件名从集合中获取对应文章的详细信息,适合需要更细粒度控制数据生成的场景。
关键注意事项
- Eleventy不支持原生嵌套分页,必须通过手动切片文章列表实现二级分页
- 确保
permalink配置唯一且符合URL规范,避免生成无效页面 - 可在集合/数据文件中提前完成文章排序,减少模板中的重复计算
内容的提问来源于stack exchange,提问作者user17938513
相关产品推荐
相关产品推荐

