基于Contentful多引用字段的Gatsby动态页面创建问题咨询
多分类关联场景的实现方案
多引用字段的过滤查询写法
Gatsby 基于 GraphQL 生成的 Schema,对列表类型的多引用关联字段,支持和单引用完全一致的嵌套过滤逻辑,不需要额外的特殊判断。只要在过滤条件中嵌套关联字段的匹配规则,就会自动匹配关联数组中任意一个元素符合条件的博客条目。
比如要匹配指定slug的分类关联的所有博客,过滤条件直接写:
query CategoryListQuery($categorySlug: String!) { allContentfulBlogPost( filter: { category2: { slug: { eq: $categorySlug } } } ) { edges { node { title slug description { description } } } } }
不需要额外写数组包含类的判断,Gatsby 的数据层已经内置了多对多关联的匹配逻辑。
动态分类页面的生成逻辑
之前用的文件系统集合路由,无法自动拆解多引用数组的路由参数——比如一篇博客绑定2个分类时,文件路由会把整个分类数组当成单个路径值,不会为每个分类独立生成页面,因此这里确实需要切换到Gatsby的createPages API实现。核心思路是不要从博客条目反推分类,直接查询独立的分类内容条目生成页面,避免重复、漏生成的问题。
具体实现步骤:
- 项目根目录下的
gatsby-node.js文件中,在createPages钩子里查询所有Contentful中的独立分类条目 - 遍历每个分类条目,生成对应路径的页面
- 将当前分类的slug作为页面上下文变量,传给分类列表模板
参考实现代码:
// gatsby-node.js exports.createPages = async ({ graphql, actions }) => { const { createPage } = actions // 直接查询所有独立的分类条目,避免从博客侧反推造成的重复、漏判 const allCategories = await graphql(` query GetAllCategories { allContentfulCategory { edges { node { slug name } } } } `) // 为每个分类生成独立页面 allCategories.data.allContentfulCategory.edges.forEach(({ node: category }) => { createPage({ path: `/categories/${category.slug}`, component: require.resolve('./src/templates/category-list.js'), context: { // 把分类slug传给模板作为查询过滤变量 currentCategorySlug: category.slug, }, }) }) }
模板文件直接复用之前写的分类列表渲染组件就行,把上下文传入的currentCategorySlug作为查询变量即可,不需要额外调整页面渲染逻辑。
实操注意事项
- 不要从博客条目的
category2数组里收集、去重分类列表:如果某个分类还没被任何博客绑定,这种方式会完全漏掉该分类的页面生成,还需要自己写额外的去重逻辑,远不如直接查询独立分类内容类型稳妥。 - 不需要为多引用的过滤写特殊的数组判断逻辑,Gatsby 的 GraphQL Schema 已经对多对多关联做了适配,嵌套的字段匹配会自动遍历数组内的所有关联条目做判断。
内容的提问来源于stack exchange,提问作者ozenK
相关产品推荐
相关产品推荐

