简体   繁体   中英

(Gatsby+Contentful) Creating Category Pages Programmatically?

I was wondering how to set up category pages programmatically with Gatsby.JS when using Contentful as CMS?

I know that in MDX you can simply configure your gatsby-node.js to something like this to create the category pages programmatically:

  result.data.allMDX.categories.distinct.forEach((category) => {
createPage({
  path: `/${category}`,
  component: path.resolve(`src/templates/category-template.js`),
  context: {
    category,
  },
})

How can I achieve the same using Contentful? I cant find any good resources online. Nobody is talking about how to set up category pages programmatically with Gatsby + Contentful.

Heres my current gatsby-node.js file:

const path = require('path')

exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions
  const result = await graphql(`
  query GetStrains {
    strains: allContentfulStrains(filter: {node_locale: {eq: "en-US"}}) {
      nodes {
        slug
      }
    }
    categories: allContentfulStrains {
      distinct(field: category)
    }
  }
  `)


  result.data.strains.nodes.forEach(strain => {
    createPage({
      path: `/strains/${strain.slug}`,
      component: path.resolve(`src/templates/strain-template.js`),
      context: {
        slug: strain.slug
      },
    })
  })

  result.data.allContentfulStrains.categories.distinct.forEach((category) => {
    createPage({
      path: `/${category}`,
      component: path.resolve(`src/templates/category-template-strains.js`),
      context: {
        category,
      },
    })
  })

As you can see above ive tried adding categories the same way as with MDX but its not working (OFC).

I would really appreciate feedback!

Since neither Contentful or Gatsby have any notion of a “category”, and there is not any convention for a page that might represent a category in your app, it's hard to expect that there would be prior art for this.

If what you're trying to do is to create pages based on the category field of another node (eg contentfulStrain ), you would instead need to query for those nodes and collate/de-dupe as needed before calling createPage for each unique category . Something like this:

const {
  data: {
    strains: { nodes: strains },
  },
} = await graphql(`
  {
    strains: allContentfulStrains(filter: { node_locale: { eq: "en-US" } }) {
      nodes {
        slug
        category
      }
    }
  }
`)

strains
  // Convert from strains to categories
  .reduce((categories, strain) => {
    categories.add(strain.category)
    return categories
  }, new Set())

  // Create a page for each category
  .forEach((category) => {
    createPage({
      // TODO: use a slugify function to create a url-friendly slug
      // for `category` before using it as the path.
      path: `/${category}`,
      component: path.resolve(`src/templates/category-template-strains.js`),
      context: {
        category,
      },
    })
  })

Then in src/templates/category-template-strains.js you would have a query that filters allContentfulStrains on the category field and retrieves any other data you need to build your category page.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM