我有多个用于不同页面类型的文件夹。 就是包含markdown文件的type1,type2等。
pages
--type1
--type2
每个文件夹中的文件都使用gatsby-transformer-remark
。
我只想查询type1,type2等的内容。
例如,我想要一个type1列表页面,其中包含所有type1页面的列表。
gatsby-config.js
{
resolve: 'gatsby-source-filesystem',
options: {
path: `${__dirname}/src/pages/type1`,
name: 'type1',
},
},
{
resolve: 'gatsby-source-filesystem',
options: {
path: `${__dirname}/src/pages/type2`,
name: 'type2',
},
},
我的假设是您可以基于name
属性进行查询。
就像是:
{
someQueryForGatsbySourceFilesystem(
filter: {
name: {
eq: "type1"
}
}
) {
edges {
node {
childMarkdownRemark {
html
}
}
}
}
}
我尝试了所有不同的查询,例如allSite和allFile,但找不到解决方案。
我也试过
allSitePlugin(filter: {
pluginOptions: {
name: {
eq: "type1"
}
}
})
这似乎没有返回我可以用来渲染内容的东西:
"Cannot query field \"childMarkdownRemark\" on type \"SitePlugin\".",
你会怎么做? 使用allFile并根据路径名进行过滤(即与文件夹type1
和markdown扩展名匹配的正则表达式)?
allFile(
filter: {
absolutePath:{regex:"/(type1)\/.*\\.md$/"}
}
) {...}
我认为您也可以使用allMarkdownRemark
过滤路径:
{
allMarkdownRemark(
sort: { order: DESC, fields: [frontmatter___date]},
filter: {fileAbsolutePath: {regex: "/(type1)/.*\\.md$/"}}
) {
edges {
node {
excerpt(pruneLength: 250)
id
frontmatter {
title
date(formatString: "MMMM DD, YYYY")
path
}
}
}
}
}
文件节点的源实例名称设置为sourceInstanceName
因此您可以将其用于查询。
使用正则表达式也是一个很好的解决方案,例如我们在gatsbyjs.org上使用了很多。
顺便说一句,如果您还没有使用它,则GraphiQL非常适合探索可用数据。
@KyleAMathews是否可以在allMarkdownRemark
查询中使用sourceInstanceName
? 我希望可以像这样为每个markdown节点获取文件节点的sourceInstanceName
,这样我可以将博客文章与项目分开,而无需在文件路径上使用正则表达式。
{
allMarkdownRemark {
edges {
node {
sourceInstanceName
}
}
}
}
但是GraphQL调试器显示sourceInstanceName
不可用。
您如何建议按源类型(例如项目和博客文章)过滤降价页面? 我当前的解决方案是获取每个降价节点的fileAbsolutePath
:
{
allMarkdownRemark {
edges {
node {
fileAbsolutePath
}
}
}
}
然后测试它是否包含某些字符串,例如/pages/blog/
或/pages/projects/
。 但是,如果gatsby站点目录本身的绝对路径本身包含以下字符串之一,则此操作将中断。 在这种情况下,您推荐什么是最佳做法? (对不起,如果我错过了文档中的内容。)
@nwshane只需查询allFile
并在那里进行过滤。 您可以按internal.mediaType
过滤降价文件。
@KyleAMathews如何将对allFile
的查询与对前事的排序结合在一起? 那可能吗?
试图找出类似的东西。
我可以按子文件夹过滤。 但我在allFile
中看不到frontmatter
allFile
。
更新:
这对我有用。
我在文件夹posts
有文件夹pages
content
,我的gatsby-config.js
指向content
。
export const query = graphql`
query IndexQuery {
allMarkdownRemark(
filter: { fileAbsolutePath: {regex : "\/posts/"} },
sort: {fields: [frontmatter___date], order: DESC},
) {
totalCount
edges {
node {
id
frontmatter {
title
slug
date(formatString: "DD MMMM YYYY")
category
}
excerpt
}
}
}
}
`;
@lukejanicke自从我上一次更新以来,我深入研究了节点系统。 减价处理程序将解析allFile
节点,然后创建新的allMarkdownRemark
节点。 因此,正如您所发现的那样,不可能在allFile
按frontmatter进行排序,因为它仅在降价解析器启动后才生成。regex有效,但就我的口味而言,它有点脆弱。 我的解决方案是通过onCreateNode
钩子将集合名称(在文件系统源插件配置中指定)从文件节点复制到markdown节点。 我前面没有代码来发布示例,但这很快,然后我可以在allMarkdownRemark
中有一个可以过滤的字段。
@KyleAMathews建议的另一种可能性(在我的情况下,源名称为projects
)
allFile(filter: {internal: {mediaType: {eq: "text/markdown"}}, sourceInstanceName: {eq: "projects"}}) {
edges {
node {
childMarkdownRemark {
frontmatter {
...
}
}
}
}
}
@gbouteiller是的,这将获得frontmatter
并允许一个人按sourceInstanceName
进行过滤。 麻烦的是,您不能使用这种方法对frontmatter
的任何内容进行排序。 似乎人们在这里谈论博客文章,通常按日期排序。 该日期通常存储在frontmatter
。
有没有办法通过某种东西做frontmatter
和过滤器由sourceInstanceName
默认。 没有将sourceInstanceName
从File
节点复制到markdownRemark
节点。 唯一的选择是使用正则表达式或按照我之前的文章复制一些数据。
如果不需要排序(在许多情况下可能是正确的),则您的方法很有意义。 我还没有意识到childMarkdownRemark
可以作为file
上的一个字段使用,这非常有用,感谢您的分享。
遇到了这个问题,对于“ name”字段不能与markdownRemark配合使用感到非常失望。 我们可以做些小事来传递这些信息吗?
编辑:经过一番混乱后,我意识到id字段公开了路径,您可以基于此进行过滤:
query AllQuery {
DSes: allMarkdownRemark(
limit: 3
filter: { id: { regex: "/_design-systems/" } }
) {
edges {
node {
frontmatter {
title
date
company
link
image
description
}
fields {
slug
}
}
}
}
Articles: allMarkdownRemark(
limit: 3
filter: { id: { regex: "/_articles/" } }
) {
edges {
node {
frontmatter {
title
date
company
link
image
description
}
fields {
slug
}
}
}
}
}
源文件系统中的name
字段对于gatsby-transformer-remark仍然没有任何作用,因为gatsby-transformer-remark
从来没有改善过dx作为可查询/可过滤字段存在没有gatsby-source-filesystem
。
@ tsiq-swyx我正在使用类似的方法将collection
字段从File
传递到MarkdownRemark
。
exports.onCreateNode = ({ node, boundActionCreators, getNode }) => {
const { createNodeField } = boundActionCreators
if (_.get(node, 'internal.type') === `MarkdownRemark`) {
// Get the parent node
const parent = getNode(_.get(node, 'parent'))
// Create a field on this node for the "collection" of the parent
// NOTE: This is necessary so we can filter `allMarkdownRemark` by
// `collection` otherwise there is no way to filter for only markdown
// documents of type `post`.
createNodeField({
node,
name: 'collection',
value: _.get(parent, 'sourceInstanceName'),
})
regex
方法确实有效,但它很脆弱。
@chmac这非常聪明,它可以工作,谢谢您分享您的解决方案。 @KyleAMathews对标记您(如果还有其他人标记,gatsby-source-filesystem
是否可以这种方式工作(将sourceInstanceName传递给节点字段或其他字段)?
@ tsiq-swyx我不确定100%,但是我想这可能是一个相当简单的请求! ;-)
我认为gatsby维护者对这些事情有强烈的看法,因此我认为在发送未经请求的PR之前值得讨论:)
好的,我可以使用它,但是我的createPages导出仅使用一个模板
令人惊讶的是,使用gatsby-source-filesystem
完全不需要graphql中的AllFile。 这可能会带来混乱,并且不会在文档中反映出来。
我在用
const { createPage } = actions
const result = await graphql(`
query {
allMarkdownRemark {
edges {
node {
fields {
slug
}
frontmatter {
lang
}
}
}
}
}
`)
并且它可以毫无问题地创建页面。 但是不确定是否相同的原理适用于gatsby-source-git
谢谢@chmac
我必须基于gatsby-source-filesystem
名称创建页面...
所以这是我的解决方案:
const { createFilePath } = require("gatsby-source-filesystem")
exports.onCreateNode = ({ node, actions, getNode }) => {
const { createNodeField } = actions
if (node.internal.type === `Mdx` && getNode(node.parent).sourceInstanceName === "careers") {
const value = createFilePath({ node, getNode })
createNodeField({
name: "slug",
node,
value: `/careers${value}`
})
}
}
这很有趣,从来没有找到这样的选项node.parent存在
2020年4月27日星期一,诺曼·古尔[email protected]写道:
谢谢@chmac https://github.com/chmac
我必须基于gatsby-source-filesystem名称创建页面...
所以这是我的解决方案:
const {createFilePath} = require(“ gatsby-source-filesystem”)
exports.onCreateNode =({{节点,操作,getNode})=> {
const {createNodeField} =操作如果(node.internal.type ===
Mdx
&& getNode(node.parent).sourceInstanceName ===“职业”){
const value = createFilePath({node,getNode})createNodeField({ name: "slug", node, value: `/careers${value}` })
}
}-
您收到此邮件是因为您发表了评论。
直接回复此电子邮件,在GitHub上查看
https://github.com/gatsbyjs/gatsby/issues/1634#issuecomment-619670883 ,
或退订
https://github.com/notifications/unsubscribe-auth/AAEQPFX6KR7NUIY33Q7V4MDROTS7PANCNFSM4DUUPK6A
。
在阅读了此线程之后,我处于一种我认为是相当普遍的情况下; 我认为,最好的非hacky解决方案是:
{
allMarkdownRemark(filter: {fileAbsolutePath: {regex: "/projects/"}}) {
edges {
node {
frontmatter {
title
}
}
}
}
}
我的projects
类型的内容在/content/projects/
。
最有用的评论
@ tsiq-swyx我正在使用类似的方法将
collection
字段从File
传递到MarkdownRemark
。regex
方法确实有效,但它很脆弱。