带有动态页面的 GraphQL 查询过滤器

时间:2021-02-08 06:52:11

标签: graphql gatsby

我正在为我的所有类别创建动态页面。这些存储在 GraphCMS 的 CMS 中,因此添加新类别将生成一个新类别按钮和一个页面。

在动态生成的页面上,我想显示具有关联类别的所有相关帖子。

我使用 GatsbyJS 和 GraphQL 查询从 GraphCMS 获取数据。

这是我的 gatsby-node.js 文件中的类别查询:

categories: allGraphCmsCategory {
          nodes {
            title
            slug
            description
            id
          }
        }

这就是我创建页面的方式。代码在 gatsby-node.js 中:

data.categories.nodes.forEach(category => {
    createPage({
      component: path.resolve("./src/templates/category-page.tsx"),
      context: {
        category,
      },
      path: `/articles/categories/${category.slug}`,
    })
  })

这是名为“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)``

这是我的帖子查询:

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
            }
          }
        }

你能指导我正确的方向吗?我正在考虑启用过滤的 GraphQL 查询,但我不确定当页面必须是动态的时我将如何实现这一点。

1 个答案:

答案 0 :(得分:1)

您有两个选择。您可以修改 category 节点以通过 customizing the Graphql schema 添加相关帖子,或者您可以进行两个单独的查询并过滤类别。

关于数据结构的信息不足,无法为修改 GraphQL 架构提供可靠的答案,因此我将重点介绍第二种方法。

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
          }
        }
      }
    }
  }
`

注意:我假设了默认的 Markdown 数据结构,如果它与您的不匹配,请根据您的需要进行调整。

这个想法是创建一个新的查询来获取所有帖子,在那里,信息将被数据保存(从 props.data 解构),然后,用类别的标题过滤它们(假设帖子将有一个类别字段,它必须有一个)。