Reputation: 850
I'm creating dynamic pages for all my categories. Those are stored within our CMS from GraphCMS, so adding new categories would generate a new category button as well as a page.
On the dynamically generated page, I would like to show all relevant posts with the associated category.
I'm using GatsbyJS and GraphQL queries to fetch the data from GraphCMS.
This is the Category query in my gatsby-node.js file:
categories: allGraphCmsCategory {
nodes {
title
slug
description
id
}
}
This is how I create the pages. The code is within the gatsby-node.js:
data.categories.nodes.forEach(category => {
createPage({
component: path.resolve("./src/templates/category-page.tsx"),
context: {
category,
},
path: `/articles/categories/${category.slug}`,
})
})
This is the template file for the category page named "category-page.tsx":
import React from "react"
import styled from "styled-components"
import { H1, BodyMain } from "../components/styles/TextStyles"
export default function CategoryPageTemplate({ pageContext: { category } }) {
return (
<Wrapper>
<HeaderWrapper>
<TextWrapper>
<TitleWrapper>{category.title}</TitleWrapper>
<DescriptionWrapper>{category.description}</DescriptionWrapper>
</TextWrapper>
</HeaderWrapper>
</Wrapper>
)
}
const Wrapper = styled.div``
const HeaderWrapper = styled.div`
min-height: 250px;
display: grid;
justify-content: center;
align-items: center;
padding: 30px;
`
const TextWrapper = styled.div`
display: grid;
grid-gap: 1rem;
text-align: center;
`
const TitleWrapper = styled(H1)`
padding: 0.2rem;
font-weight: 900;
background: -webkit-linear-gradient(left, #7230ce, #3E16BB)};
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
`
const DescriptionWrapper = styled(BodyMain)``
This is my query for post:
allGraphCmsPost(sort: { fields: date, order: ASC }) {
edges {
nextPost: next {
slug
title
}
page: node {
id
author {
id
name
title
}
content {
markdownNode {
childMdx {
body
}
}
}
date: formattedDate
excerpt
seo {
description
image {
url
}
keywords
title
}
slug
title
}
previousPost: previous {
slug
title
}
}
}
Can you guide me in the right direction? I'm thinking about GraphQL query with filtering on, but I'm not certain how I would accomplish that when the pages has to be dynamic.
Upvotes: 0
Views: 1277
Reputation: 29320
You have two options. You can modify the category
node to add the related posts by customizing the Graphql schema or you can make two separate queries and filter for the category.
There's not enough information about the data structure to provide a solid answer to modify the GraphQL schema so I will focus on the second approach.
import React from "react"
import styled from "styled-components"
import { H1, BodyMain } from "../components/styles/TextStyles"
export default function CategoryPageTemplate({ pageContext: { category }, data }) {
const filteredPosts = data.allMarkdownRemark.edges.filter(({ node }) =>{
node.frontmatter.category == category.title
});
return (
<Wrapper>
<HeaderWrapper>
<TextWrapper>
<TitleWrapper>{category.title}</TitleWrapper>
<DescriptionWrapper>{category.description}</DescriptionWrapper>
</TextWrapper>
</HeaderWrapper>
</Wrapper>
)
}
const Wrapper = styled.div``
// omitted the styles to avoid a huge answer
export const pageQuery = graphql`
query {
allMarkdownRemark(sort: { order: DESC, fields: [frontmatter___date] }) {
edges {
node {
id
excerpt(pruneLength: 250)
frontmatter {
date(formatString: "MMMM DD, YYYY")
slug
category
title
}
}
}
}
}
`
Note: I've assumed a default markdown data structure, adapt it to your needs if it doesn't match yours.
The idea is to create a new query to get all posts and there, the information will be holded by data (destructured from props.data
), then, filter them with the title of the category (assuming that the posts will have a category field, it must have one).
Upvotes: 1