如何创建单个 Gatsby 页面以按标签/类别显示和过滤所有博客文章

2024-01-26

您好,我正在使用 Gatsby 和 Netlify CMS 构建一个博客。我从 gatsby-starter-netlify-cms 模板开始。

我有/blog我当前显示所有帖子以及所有标签列表的页面。 当用户点击标签时,当前会重定向到tags/name-of-tag页面,其中显示所有带有此类标签的帖子的列表。

我想要什么就是直接对列表进行过滤/blog页。 这样,我将只有一个页面来按标签(也可能按术语搜索)显示和过滤博客文章。

所以标签链接应该重定向到/blog?tag-name或类似的东西。 我不知道如何告诉 Gatsby 创建一个可以注入的单个页面filter值以便将其传递给页面查询。

就是这样/tags/当前创建的页面:

// Tag pages:
    let tags = []
    // Iterate through each post, putting all found tags into `tags`
    posts.forEach((edge) => {
      if (_.get(edge, `node.frontmatter.tags`)) {
        tags = tags.concat(edge.node.frontmatter.tags)
      }
    })
    // Eliminate duplicate tags
    tags = _.uniq(tags)

    // Make tag pages
    tags.forEach((tag) => {
      const tagPath = `/tags/${_.kebabCase(tag)}/`

      createPage({
        path: tagPath,
        component: path.resolve(`src/templates/tags.js`),
        context: {
          tag,
        },
      })
    })

这是我的博客页面查询(我希望能够按标签过滤):

export const blogPageQuery = graphql`
  query BlogPageTemplate {
    markdownRemark(frontmatter: { templateKey: { eq: "blog-page" } }) {
      frontmatter {
        image {
          childImageSharp {
            fluid(maxWidth: 2048, quality: 80) {
              ...GatsbyImageSharpFluid
            }
          }
        }
        heading
        subheading
      }
    }
    allMarkdownRemark(
      sort: { order: DESC, fields: [frontmatter___date] }
      filter: { frontmatter: { templateKey: { eq: "blog-post" } } }
    ) {
      edges {
        node {
          id
          fields {
            slug
          }
          excerpt(pruneLength: 180)
          frontmatter {
            date(formatString: "MMMM DD, YYYY")
            title
            description
            featuredpost
            featuredimage {
              childImageSharp {
                fluid(quality: 50, maxWidth: 512) {
                  ...GatsbyImageSharpFluid
                }
              }
            }
          }
        }
      }
    }
  }
`

我不知道如何告诉盖茨比创建一个页面 注入的可能性filter值以便将其传递到页面 询问。

你不能。在页面查询中过滤数据的唯一方法是使用上下文传递数据。就像您在标签页面中所做的那样:

  createPage({
    path: tagPath,
    component: path.resolve(`src/templates/tags.js`),
    context: {
      tag,
    },
  })

最简单和本机的方法是使用/tag/tag-namepage,旨在按标签名称过滤,否则,您将需要获取 URL 参数并在 JavaScript 中使用它filter https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Array/filter函数过滤页面查询中的所有数据。由于您缺少博客页面的渲染部分...类似这种方法应该有效:

const BlogTemplate=({ data }){
    if(typeof window !== "undefined"){
      const queryString = window.location.search;
      const urlParams = new URLSearchParams(queryString);
      const urlTag= urlParams.get('tag');
      const filteredPosts= data.allMarkdownRemark.edges.node.filter(node=> node.frontmatter.tag.includes(urlTag))
      const loopData= urlParams.has('tag') ? filteredPosts : data
   }
   
return loopData.allMarkdownRemark.edges.node.map(node=> <h1 key={node.title}>{node.title}</h1>)

}

注意:当然,可以根据您的需要进行调整,但要明白其中的意思。

另请注意,您需要将所有窗口逻辑包装在typeof window !== "undefined"条件,因为在苏维埃社会主义共和国window(和其他全局对象)不可用 https://www.gatsbyjs.com/docs/debugging-html-builds/.

关键部分是使用还是使用data或你的filteredPosts取决于URL参数是否存在,因此如果存在,则需要过滤数据,否则,需要使用“默认”data(未过滤)。

很难猜测代码的行为方式,但这个想法依赖于根据 URL 更改可迭代数据,如果需要,请使用一些钩子。

根据您的查询,您的博客似乎不包含任何内容tag博客模板查询中的字段,因此您需要添加它以允许filter循环工作。

一旦代码正常工作,您将需要添加适当的控件以避免在缺少某些字段时发生代码破坏,但要遵循的想法和路径是这样的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何创建单个 Gatsby 页面以按标签/类别显示和过滤所有博客文章 的相关文章

随机推荐