javascript - 尝试为类别或标签构建模板页面时,我在 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
?
编辑:
剥离沙箱中发生的事情和问题:
尝试将节点从 更改为id
,slug
结果是一样的:
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
解决方案
有几件事可能会导致问题:
您的
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 页面,默认情况下会打印所有创建的页面。
推荐阅读
- mongodb - 带有外域_id的mongodb $lookup
- git - 我应该如何删除存储在 vscode 中的凭据
- assembly - 如何理解下面的代码片段
- flutter - Flutter,当父级滚动高度较长时如何处理PDF Viewer的滚动?
- lightweight-charts - 将部分数据设置为时间范围的系列
- java - 如何将输入设置为公共常量
- c++ - FFT 的真实输入,然后 iFFT 回到一维数组中的真实数据
- foreach - 使用 Mule4 将 CSV 文件写入(附加)到变量中
- excel - 如何在 Excel VBA 中打开“带有新的 PPT 文件”选项
- python - 根据列表中的列名选择列