关于 javascript:GatsbyJS GraphQL 查询中的作用域文件夹结构

Scoping folder structure in GraphQL Queries with GatsbyJS

我确实有分类、片段和图片。它们都是级联的;典型的亲子关系。并且文件夹结构已经代表了这个层次结构。最后,我将更详细地解释我的主要问题。

文件夹结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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:

1
2
3
4
5
6
7
8
9
// ...
{
  resolve: 'gatsby-source-filesystem',
  options: {
    name: 'work',
    path: `${__dirname}/work/`,
  },
},
// ...

为了解析文件,我使用 gatsby-source-filesystem 插件。因此,我可以通过 sourceInstanceName: { eq:"work" }.

查询该文件夹

gatsby-node.js:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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,  
        })
      }
    }
  }
}

此代码可帮助我标记类别以供以后使用,例如在概览页面上显示类别列表。

示例查询:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
  allDirectory(
    filter: {
      sourceInstanceName: { eq:"work" }
      relativeDirectory: { eq:"" }
    }
  ) {
    edges {
      node {
        dir
        name
        extension
        relativeDirectory
        relativePath
      }
    }
  }
}

查询所有类别。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
  allDirectory(
    filter: {
      sourceInstanceName: { eq:"work" }
      relativeDirectory: { eq:"drawing" }
    }
  ) {
    edges {
      node {
        dir
        name
        extension
        relativeDirectory
        relativePath
      }
    }
  }
}

查询类别 drawing 的所有部分。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
  allFile(
    filter: {
      sourceInstanceName: { eq:"work" }
      extension: { in: ["jpg","jpeg","png"] }
        relativeDirectory: { eq:"drawing/drawing-1" }
    }
  ) {
    edges {
      node {
        dir
        name
        extension
        relativeDirectory
        relativePath
      }
    }
  }
}

查询分类drawingdrawing-1的所有图片。

问题:

在最好的情况下,我想遍历每个类别并显示带有 index.md 中的图片和描述的工件。但是我怎样才能分别提取类别来查询碎片呢?我应该如何将这些实体与 Gatsby 映射在一起?我的概念是否具有误导性?如果您有什么好的建议,我应该考虑什么来实现我的目标,我会很高兴的。

编辑:

现在我正在摆弄 sourceNodes() 并从文件夹结构中创建抽象节点。所需的 JSON 可能如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
{
 "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未公开的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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
                })
            }
        }
    }
}

相应的查询可能如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    {
      allDirectory(
        filter: {
          sourceInstanceName: { eq:"work" }
            relativeDirectory: { eq:"" }
        }
      ) {
        edges {
          node {
            name
            relativePath
            children {
              __typename ... on Directory {
                name
                relativePath
              }
            }
          }
        }
      }
    }

输出看起来像:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
    {
     "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