在尝试为类别或标签构建模板页面时,我对 gatsby-node 的误解是什么?
What am I misunderstanding in gatsby-node when trying to build a template page for categories or tags?
尝试学习 Gatsby 在为类别构建分页页面时,我很困惑自己做错了什么。如果 post 的类别是从以下内容的前言创建的:
---
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 我没有任何问题(或者我应该说抛出的问题)单 post 生成但控制台显示:
Failed to load resource: the server responded with a status of 404
(Not Found)
单击类别而不是单击 <Link>
转到单个 post 时,文件:
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
在 GraphiQL 中,我的两个查询都有效,示例仅针对一个类别进行过滤:
{
"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
}
}
}
}
}
研究:
- Creating Tags Pages for Blog Posts
- Wordpress + Gatsby: List all posts for each categories?
- gatsby-advanced-starter
为什么当我单击 post 中的类别时,如果我将其添加到 header 中,它会转到 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 页面,默认情况下,它会打印所有已创建的页面。
在 GraphiQL 中进一步研究和测试后,我在 allMDX 中找到了 distinct
,我能够查询 frontmatter 类别或标签:
foo.mdx 前言:
---
date: '2017-08-10'
title: 'Sweet Pandas Eating Sweets'
slug: 'sweet-pandas-eating-sweets'
description: 'Something different to post'
category: ['sweet', 'yep', 'two']
---
盖茨比-node.js:
exports.createPages = async ({ actions, graphql }) => {
const catsQuery = await graphql(`
query {
allMdx(filter: { fileAbsolutePath: { regex: "/content/" } }) {
distinct(field: frontmatter___category)
}
}
`)
catsQuery.data.allMdx.distinct.forEach(category => {
actions.createPage({
path: `/category/${category}`,
component: require.resolve(`./src/templates/category.js`),
context: { category },
})
})
}
尝试学习 Gatsby 在为类别构建分页页面时,我很困惑自己做错了什么。如果 post 的类别是从以下内容的前言创建的:
---
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 我没有任何问题(或者我应该说抛出的问题)单 post 生成但控制台显示:
Failed to load resource: the server responded with a status of 404 (Not Found)
单击类别而不是单击 <Link>
转到单个 post 时,文件:
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
在 GraphiQL 中,我的两个查询都有效,示例仅针对一个类别进行过滤:
{
"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
}
}
}
}
}
研究:
- Creating Tags Pages for Blog Posts
- Wordpress + Gatsby: List all posts for each categories?
- gatsby-advanced-starter
为什么当我单击 post 中的类别时,如果我将其添加到 header 中,它会转到 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 页面,默认情况下,它会打印所有已创建的页面。
在 GraphiQL 中进一步研究和测试后,我在 allMDX 中找到了 distinct
,我能够查询 frontmatter 类别或标签:
foo.mdx 前言:
---
date: '2017-08-10'
title: 'Sweet Pandas Eating Sweets'
slug: 'sweet-pandas-eating-sweets'
description: 'Something different to post'
category: ['sweet', 'yep', 'two']
---
盖茨比-node.js:
exports.createPages = async ({ actions, graphql }) => {
const catsQuery = await graphql(`
query {
allMdx(filter: { fileAbsolutePath: { regex: "/content/" } }) {
distinct(field: frontmatter___category)
}
}
`)
catsQuery.data.allMdx.distinct.forEach(category => {
actions.createPage({
path: `/category/${category}`,
component: require.resolve(`./src/templates/category.js`),
context: { category },
})
})
}