首页 > 解决方案 > 尝试为类别或标签构建模板页面时,我在 gatsby-node 中误解了什么?

问题描述

尝试学习 Gatsby 在为类别构建分页页面时,我对自己做错了什么感到困惑。如果帖子具有从以下方面创建的类别:

---
date: '2017-08-10'
title: 'Sweet Pandas Eating Sweets'
slug: 'sweet-pandas-eating-sweets'
description: 'Something different to post'
category: ['sweet', 'yep', 'two']
tags: ['3', '2']
---

在我的gatsby-node.js中,我没有任何问题(或我应该说的抛出问题)与单个帖子生成,但控制台显示:

加载资源失败:服务器响应状态为 404(未找到)

当点击类别而不是<Link>点击进入单个帖子时,文件:

exports.createPages = async ({ actions, graphql }) => {
  const { data } = await graphql(`
    query {
      allMdx(sort: { fields: frontmatter___date, order: DESC }) {
        edges {
          node {
            id
            frontmatter {
              title
              slug
              tags
              category
              date
            }
          }
        }
      }
    }
  `)

  if (data.errors) {
    console.error(data.errors)
    throw data.errors
  }

  // const tagSet = new Set()
  // const categorySet = new Set()

  data.allMdx.edges.map(edge => {
    const slug = edge.node.frontmatter.slug
    const id = edge.node.id
    actions.createPage({
      path: slug,
      component: require.resolve(`./src/templates/singlePost.js`),
      context: { id },
    })
  })

  const postPerPage = 3
  const numPages = Math.ceil(data.allMdx.edges.length / postPerPage)
  Array.from({ length: numPages }).forEach((_, i) => {
    actions.createPage({
      path: i === 0 ? `/` : `/${i + 1}`,
      component: require.resolve(`./src/templates/category.js`),
      context: {
        limit: postPerPage,
        skip: i * postPerPage,
        numPages,
        currentPage: i + 1,
      },
    })
  })
}

并在templates/category.js

import React from 'react'
import { graphql } from 'gatsby'

// Components
import Layout from '../components/Layout'

const category = ({ location, pageContext, data }) => {
  const { currentPage, numPages } = pageContext
  const isFirst = currentPage === 1
  const isLast = currentPage === numPages
  const prevPage = currentPage - 1 === 1 ? '/' : `/${currentPage - 1}`
  const nextPage = `/${currentPage + 1}`
  const posts = data.allMdx.edges

  console.log('data', data)
  return (
    <>
      <Layout>categories</Layout>
    </>
  )
}

export const pageQuery = graphql`
  query CategoryQuery($id: String!, $skip: Int!, $limit: Int!) {
    allMdx(
      sort: { fields: frontmatter___date, order: DESC }
      skip: $skip
      limit: $limit
      filter: { frontmatter: { category: { eq: $id } } }
    ) {
      edges {
        node {
          id
          frontmatter {
            title
            category
            date
            description
            slug
          }
        }
      }
    }
  }
`

export default category

在 Graph i QL 中,我的两个查询都有效,例如仅过滤一个类别:

{
"id":"two"
}

询问:

query CategoryQuery($id: String!) {
  allMdx(
    sort: {fields: frontmatter___date, order: DESC}
    filter: {frontmatter: {category: {eq: $id}}}
  ) {
    edges {
      node {
        id
        frontmatter {
          title
          category
          date
          description
          slug
        }
      }
    }
  }
}

研究:

为什么当我单击帖子中的类别时,如果我将其添加到标题中,它会转到 404 页面并指示还没有页面/category

编辑:

剥离沙箱中发生的事情和问题:

编辑隐形背景

尝试将节点从 更改为idslug结果是一样的:

  tagsQuery.data.allMdx.edges.forEach(edge => {
    const slug = edge.node.frontmatter.slug
    actions.createPage({
      path: `category/${slug}`,
      component: require.resolve(`./src/templates/Category.js`),
      context: { slug },
    })
  })

从 404 页面,在它显示的页面下:

/category/undefined
/404/
/
/404.html
/post-slug
/post-slug

标签: javascriptgraphqlgatsbycategories

解决方案


有几件事可能会导致问题:

  • 您的templates/category组件必须大写:

      const Category = ({ location, pageContext, data }) => {
      const { currentPage, numPages } = pageContext
      const isFirst = currentPage === 1
      const isLast = currentPage === numPages
      const prevPage = currentPage - 1 === 1 ? '/' : `/${currentPage - 1}`
      const nextPage = `/${currentPage + 1}`
      const posts = data.allMdx.edges
    
      console.log('data', data)
      return (
        <>
          <Layout>categories</Layout>
        </>
      )
    }
    

    否则,React 将无法推断和创建有效的组件。

  • 在对您的类别或标签进行分页之前,我会尝试创建一个逐步的方法,成功创建类别模板。您正在重复使用相同的查询来创建帖子和类别,但您永远不会循环创建类别。我会将逻辑分成两个单独的 GraphQL 查询:

      exports.createPages = async ({ actions, graphql }) => {
        const postsQuery = await graphql(`
          query {
            allMdx(sort: { fields: frontmatter___date, order: DESC }) {
              edges {
                node {
                  id
                  frontmatter {
                    title
                    slug
                    tags
                    category
                    date
                  }
                }
              }
            }
          }
        `)
    
        const tagsQuery = await graphql(`
          query {
            allMdx(sort: { fields: frontmatter___date, order: DESC }) {
              edges {
                node {
                  id
                  frontmatter {
                    tags
                    category
                  }
                }
              }
            }
          }
        `)
    
    
        if (postsQuery.data.errors || tagsQuery.data.errors) {
          console.error(data.errors)
          throw data.errors
        }
    
        // const tagSet = new Set()
        // const categorySet = new Set()
    
        tagsQuery.data.allMdx.edges.map(edge => {
          const slug = edge.node.frontmatter.slug
          const id = edge.node.id
          actions.createPage({
            path: slug, // or `category/${slug}`
            component: require.resolve(`./src/templates/category.js`),
            context: { id },
          })
        })
    
    
        postsQuery.data.allMdx.edges.map(edge => {
          const slug = edge.node.frontmatter.slug
          const id = edge.node.id
          actions.createPage({
            path: slug,
            component: require.resolve(`./src/templates/singlePost.js`),
            context: { id },
          })
        })
        /*
        const postPerPage = 3
        const numPages = Math.ceil(data.allMdx.edges.length / postPerPage)
        Array.from({ length: numPages }).forEach((_, i) => {
          actions.createPage({
            path: i === 0 ? `/` : `/${i + 1}`,
            component: require.resolve(`./src/templates/category.js`),
            context: {
              limit: postPerPage,
              skip: i * postPerPage,
              numPages,
              currentPage: i + 1,
            },
          })
        })*/
      }
    

    要检查创建的页面,您始终可以在gatsby develop( localhost:8000/someOddString) 模式下查找 404 页面,默认情况下会打印所有创建的页面。


推荐阅读