使用 GatsbyJS 的 GraphQL 查询中的范围文件夹结构
Posted
技术标签:
【中文标题】使用 GatsbyJS 的 GraphQL 查询中的范围文件夹结构【英文标题】:Scoping folder structure in GraphQL Queries with GatsbyJS 【发布时间】:2019-07-25 15:32:02 【问题描述】:我确实有类别、片段和图片。它们都是级联的;典型的亲子关系。并且文件夹结构已经代表了这个层次结构。最后我会更详细地解释我的主要问题。
文件夹结构:
work
├── drawing
│ ├── drawing-1
│ │ ├── image.1.jpg
│ │ ├── image.2.jpg
│ │ ├── image.3.jpg
│ │ ├── image.jpg
│ │ └── index.md
│ └── index.md
├── sculpture
│ ├── gaehnschreier
│ │ ├── image.1.JPG
│ │ ├── image.2.jpg
│ │ ├── image.3.JPEG
│ │ ├── image.4.png
│ │ ├── image.PNG
│ │ └── index.md
│ └── index.md
└── watercolor
├── index.md
├── portrait-1
│ ├── image.jpg
│ └── index.md
└── portrait-2
├── image.jpg
└── index.md
这是一个简单的投资组合层次结构。 work
是根文件夹,有不同的类别,例如drawing
。在里面你会找到代表特定作品的文件夹。每件作品都有一个index.md
,其中包含有关该作品的详细信息和多张图片(jpeg、png 等)。
gatsby-config.js:
// ...
resolve: 'gatsby-source-filesystem',
options:
name: 'work',
path: `$__dirname/work/`,
,
,
// ...
为了解析文件,我使用了gatsby-source-filesystem
插件。所以,我可以通过sourceInstanceName: eq: "work"
查询那个文件夹。
gatsby-node.js:
exports.onCreateNode = ( node, getNode, actions ) =>
const createNodeField = actions
if (node.internal.type === `Directory`)
if (node.sourceInstanceName === `work`)
if (!node.relativeDirectory)
createNodeField(
node,
name: `workCategory`,
value: true,
)
此代码可帮助我标记类别以供以后使用,例如在概览页面上显示类别列表。
示例查询:
allDirectory(
filter:
sourceInstanceName: eq: "work"
relativeDirectory: eq: ""
)
edges
node
dir
name
extension
relativeDirectory
relativePath
查询所有类别。
allDirectory(
filter:
sourceInstanceName: eq: "work"
relativeDirectory: eq: "drawing"
)
edges
node
dir
name
extension
relativeDirectory
relativePath
查询drawing
类别的所有片段。
allFile(
filter:
sourceInstanceName: eq: "work"
extension: in: ["jpg", "jpeg", "png"]
relativeDirectory: eq: "drawing/drawing-1"
)
edges
node
dir
name
extension
relativeDirectory
relativePath
查询该作品drawing-1
在类别drawing
内的所有图片。
问题:
在最好的情况下,我想遍历每个类别并显示来自index.md
的带有图片和描述的工件。但是我怎样才能分别提取类别来查询碎片呢?我应该如何将这些实体与 Gatsby 映射在一起?我的概念是否具有误导性?如果你有什么好的建议,我应该考虑什么来实现我的目标,我会很高兴的。
编辑:
现在我正在摆弄sourceNodes()
并从文件夹结构中创建抽象节点。所需的 JSON 可能如下所示:
"data":
"allWorkCategory":
"edges": [
"node":
"path": "work/scuplture",
"children": [
"node":
"internal":
"type": "WorkItem",
"name": "Drawing 1",
"pictures":
// ...
],
"internal":
"type": "WorkCategory"
,
"node":
"path": "work/drawing",
"children": [],
"internal":
"type": "WorkCategory"
,
"node":
"path": "work/watercolor",
"children": [],
"internal":
"type": "WorkCategory"
]
【问题讨论】:
不确定您想要获得什么。您能否包含您尝试编写的查询的预期 json 结果? 我正在尝试将这些片段与其相应的父类别进行映射。当这些节点连接(子/父)时,就可以遍历整个树。 @CyrilDurand 我添加了一个示例,我认为解决方案可能与createParentChildLink
一起提供:gatsbyjs.org/docs/node-creation/…
【参考方案1】:
你可以使用createParentChildLink
method创建gatsby节点之间的父/子关系,为了找到父节点你可以使用getNodesByType
undocumented method。
const path = require('path')
exports.onCreateNode = (
node,
getNodesByType,
actions
) =>
const
createParentChildLink
= actions
if (node.internal.type === 'Directory')
if (node.sourceInstanceName === 'work')
// in some case the trailing slash is missing.
// Always add it and normalize the path to remove duplication
const parentDirectory = path.normalize(node.dir + '/')
const parent = getNodesByType('Directory').find(
n => path.normalize(n.absolutePath + '/') === parentDirectory
)
if (parent)
node.parent = parent.id
createParentChildLink(
child: node,
parent: parent
)
相应的查询可能如下所示:
allDirectory(
filter:
sourceInstanceName: eq: "work"
relativeDirectory: eq: ""
)
edges
node
name
relativePath
children
__typename ... on Directory
name
relativePath
输出如下:
"data":
"allDirectory":
"edges": [
"node":
"name": "drawing",
"relativePath": "drawing",
"children": [
"__typename": "Directory",
"name": "drawing-1",
"relativePath": "drawing/drawing-1"
]
,
"node":
"name": "sculpture",
"relativePath": "sculpture",
"children": [
"__typename": "Directory",
"name": "gaehnschreier",
"relativePath": "sculpture/gaehnschreier"
]
,
"node":
"name": "watercolor",
"relativePath": "watercolor",
"children": [
"__typename": "Directory",
"name": "portrait-1",
"relativePath": "watercolor/portrait-1"
,
"__typename": "Directory",
"name": "portrait-2",
"relativePath": "watercolor/portrait-2"
]
]
为了解释,__typename ... on Directory
让你有机会整体查询对应的节点。否则,您将仅获得子节点的 ID。为了更好地理解,请访问:https://graphql.org/learn/schema/#union-types
【讨论】:
好的,这很完美。但实际上我想查询完整的节点。那么,如何才能访问其余的数据呢?现在我只能访问id
、children
、parent
和__typename
。以上是关于使用 GatsbyJS 的 GraphQL 查询中的范围文件夹结构的主要内容,如果未能解决你的问题,请参考以下文章
GatsbyJS - 如何在 GraphQL 中查询长文本内容字段
如何使用 GatsbyJS 和 GraphQL 查询和显示包含多个图像的文件夹
GatsbyJS 网站的非页面组件中的 GraphQL 查询投诉