Javascript 如何创建一个Gatsby页面,按标签/类别显示和过滤所有博客文章
你好,我正在用盖茨比和Netlify CMS建立一个博客。我从盖茨比初学者netlify cms模板开始 我有一个Javascript 如何创建一个Gatsby页面,按标签/类别显示和过滤所有博客文章,javascript,reactjs,gatsby,netlify,netlify-cms,Javascript,Reactjs,Gatsby,Netlify,Netlify Cms,你好,我正在用盖茨比和Netlify CMS建立一个博客。我从盖茨比初学者netlify cms模板开始 我有一个/blog页面,在那里我当前显示了所有帖子以及所有标签的列表。 当用户单击标签时,它当前被重定向到tags/name of tag页面,在该页面上显示所有贴有类似标签的帖子的列表 我想要的是直接过滤/blog页面上的列表。 这样,我就只有一个页面可以按标签显示和过滤博客文章(可能还有术语搜索) 因此标记链接应该重定向到/blog?标记名或类似的内容。 我不知道如何告诉盖茨比创建一个可
/blog
页面,在那里我当前显示了所有帖子以及所有标签的列表。
当用户单击标签时,它当前被重定向到tags/name of tag
页面,在该页面上显示所有贴有类似标签的帖子的列表
我想要的是直接过滤/blog
页面上的列表。
这样,我就只有一个页面可以按标签显示和过滤博客文章(可能还有术语搜索)
因此标记链接应该重定向到/blog?标记名或类似的内容。
我不知道如何告诉盖茨比创建一个可以插入过滤器
值的页面,以便将其传递给页面查询
这就是当前创建/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,
},
})
})
这是我的博客页面查询(我希望能够通过标记进行筛选):
我不知道如何告诉盖茨比用
可以插入过滤器
值以将其传递到页面
询问
你不能。过滤页面查询中数据的唯一方法是使用上下文传递数据。就像您在标签页中所做的那样:
createPage({
path: tagPath,
component: path.resolve(`src/templates/tags.js`),
context: {
tag,
},
})
最简单的本地方法是使用/tag/tag name
页面,该页面旨在按标记名进行过滤,否则,您需要获取URL参数并在JavaScript函数中使用它来过滤页面查询中的所有数据。由于您缺少博客页面的呈现部分。。。类似于这种方法的方法应该有效:
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>)
}
constblogtemplate=({data}){
如果(窗口类型!=“未定义”){
const queryString=window.location.search;
const urlParams=新的URLSearchParams(queryString);
const urlTag=urlParams.get('tag');
const filteredPosts=data.allmarkdownmark.edges.node.filter(node=>node.frontmatter.tag.includes(urlTag))
const loopData=urlParams.has('tag')?filteredPosts:data
}
返回loopData.allMarkdownRemark.edges.node.map(node=>{node.title})
}
注意:当然,根据你的需要调整它,但要有想法
还请注意,您需要将所有窗口逻辑包装在typeof window!==“未定义”
条件,自
关键部分是根据URL参数的存在来使用数据
还是您的过滤器主题
,因此如果它存在,您将需要过滤数据,否则,您需要使用“默认”数据
(未过滤)
很难猜测代码将如何运行,但是这个想法依赖于根据URL更改可编辑的数据,如果需要,使用一些钩子
根据您的查询,您的博客在博客模板查询中似乎不包含任何标记
字段,因此您需要添加它以允许过滤器
循环工作
代码运行后,您需要添加适当的控件,以避免在缺少某个字段时出现代码中断,但思路和路径如下。到目前为止您做了哪些尝试?我想在从页面查询中获取所有帖子的数组后直接过滤列表,但是我不知道如何从另一个链接触发过滤(比如在另一个页面中单击博客帖子标签)。最好的方法是使用盖茨比的页面节点创建和graphql,但我不知道如何…您的代码作为一个魅力(在适应了我的变量名等之后),谢谢!我得到的唯一错误来自这一行:const-filteredPosts=data.allmarkdownmark.edges.node.filter(node=>node.frontmatter.tag.includes(urlTag))
应该是const-filteredPosts=data.allmarkdownmark.edges.node.filter(node=>return-node.frontmatter.tag.includes(urlTag))
因为.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>)
}