如何创建一个单独的盖茨比页面来显示和过滤所有的博客文章的标签/类别



你好,我正在使用盖茨比和netflix CMS建立一个博客。我从gatsby-starter- netfly -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-name页面,该页面旨在通过标记名称进行过滤,否则,您将需要获取URL参数并在JavaScriptfilter函数中使用它来过滤页面查询中的所有数据。既然你缺少你的博客页面的渲染部分…类似这样的方法应该可以工作:

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"条件中,因为在SSR中window(和其他全局对象)不可用。

关键部分是根据URL参数的存在来使用datafilteredPosts,所以如果它存在,则需要过滤数据,否则需要使用"default"data(过滤)。

很难猜测代码将如何表现,但是这个想法依赖于根据URL更改可迭代数据,如果需要的话使用一些钩子。

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

一旦代码工作,您将需要添加适当的控件,以避免某些字段丢失时的代码破坏,但思路和路径是这样的。

最新更新