javascript - 使用 GatsbyJS 的 GraphQL 查询中的范围文件夹结构
问题描述
我确实有类别、片段和图片。它们都是级联的;典型的亲子关系。并且文件夹结构已经代表了这个层次结构。最后,我将更详细地解释我的主要问题。
文件夹结构:
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 等)。
盖茨比-config.js:
// ...
{
resolve: 'gatsby-source-filesystem',
options: {
name: 'work',
path: `${__dirname}/work/`,
},
},
// ...
为了解析文件,我使用gatsby-source-filesystem
插件。所以,我可以通过查询该文件夹sourceInstanceName: { eq: "work" }
。
盖茨比节点.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"
}
}
}
]
}
}
}
解决方案
createParentChildLink
您可以使用方法创建gatsby节点之间的父/子关系,为了找到父节点可以使用getNodesByType
未记录的方法。
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
推荐阅读
- javascript - 带有可拖动手柄的垂直拆分面板以调整面板的高度
- python - 你如何找到一个似乎没有在任何地方定义的 python 模块?
- wordpress - 单击wpml中的链接时如何保持当前语言
- android - Android - JSON 抛出异常
- google-bigquery - 在 Big Query 中使用通配符进行分组
- selenium - 无论我使用什么定位器,我都无法使用 Selenium 单击此按钮
- python - Pyspark:\Anaconda3\envs\xgboost\python.exe] 此时出乎意料
- reactjs - 创建 React 应用程序 - 控制台 lint 警告与 eslintrc 不匹配
- c# - 读取文件中的特定行/int 并转换为其他 C#
- javascript - 未捕获的类型错误:无法读取 Component.setState 处未定义的属性“enqueueSetState”