您好,我正在使用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
}
}
}
}
}
}
}
}
`
我不确定如何告诉Gatsby创建单个页面并可能注入
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参数的存在来使用data
或使用filteredPosts
,因此,如果存在,则需要过滤数据,否则,需要使用“默认” data
(未过滤)。
很难猜测代码的行为方式,但是这个想法依赖于根据URL更改可迭代数据,如果需要,可以使用一些钩子。
根据您的查询,您的博客似乎tag
在博客模板查询中不包含任何字段,因此您需要添加它以使filter
循环起作用。
代码正常工作后,您将需要添加适当的控件,以避免在缺少某些字段时导致代码中断,但是,思路和遵循的方法是这样。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句