Javascript 使用GatsbyJS在GraphQL查询中定义文件夹结构

Javascript 使用GatsbyJS在GraphQL查询中定义文件夹结构,javascript,typescript,filesystems,graphql,gatsby,Javascript,Typescript,Filesystems,Graphql,Gatsby,我有分类、作品和图片。它们都是按级联顺序排列的;典型的亲子关系。文件夹结构已经表示了这个层次结构。最后,我将更详细地解释我的主要问题 文件夹结构: work ├── drawing │   ├── drawing-1 │   │   ├── image.1.jpg │   │   ├── image.2.jpg │   │   ├── image.3.jpg │   │   ├── image.jpg │   │   └── index.md │   └── index.md ├── sculp

我有分类、作品和图片。它们都是按级联顺序排列的;典型的亲子关系。文件夹结构已经表示了这个层次结构。最后,我将更详细地解释我的主要问题

文件夹结构:

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
// ...
{
  resolve: 'gatsby-source-filesystem',
  options: {
    name: 'work',
    path: `${__dirname}/work/`,
  },
},
// ...
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
      }
    }
  }
}
这是一个简单的投资组合层次结构<代码>工作是根文件夹,具有不同的类别,例如
绘图
。在里面你会找到文件夹,它们代表一个特定的部分。每幅作品都有一个
index.md
,其中包含关于该作品的详细信息和多幅图像(jpeg、png等)


gatsby config.js:

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
// ...
{
  resolve: 'gatsby-source-filesystem',
  options: {
    name: 'work',
    path: `${__dirname}/work/`,
  },
},
// ...
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
      }
    }
  }
}
为了解析文件,我使用了
gatsby源文件系统
插件。因此,我可以通过
sourceInstanceName:{eq:“work”}
查询该文件夹


gatsby node.js:

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
// ...
{
  resolve: 'gatsby-source-filesystem',
  options: {
    name: 'work',
    path: `${__dirname}/work/`,
  },
},
// ...
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
      }
    }
  }
}
此代码帮助我标记类别以备将来使用,例如在概览页面上显示类别列表


查询示例:

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
// ...
{
  resolve: 'gatsby-source-filesystem',
  options: {
    name: 'work',
    path: `${__dirname}/work/`,
  },
},
// ...
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
      }
    }
  }
}
查询所有类别


查询类别
图纸的所有零件


查询工件的所有图片
drawing-1
内部类别
drawing


问题:

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
// ...
{
  resolve: 'gatsby-source-filesystem',
  options: {
    name: 'work',
    path: `${__dirname}/work/`,
  },
},
// ...
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
      }
    }
  }
}
在最好的情况下,我希望遍历每个类别,并在
index.md
中显示带有图片和描述的作品。但是,如何单独提取类别以查询片段?我应该如何与盖茨比一起映射这些实体?我的概念错了吗?如果你有什么好的建议,我应该想些什么来实现我的目标,我会很高兴的

编辑:

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
// ...
{
  resolve: 'gatsby-source-filesystem',
  options: {
    name: 'work',
    path: `${__dirname}/work/`,
  },
},
// ...
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
      }
    }
  }
}
现在我正在摆弄
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"
            }
          }
        }
      ]
    }
  }
}

可以使用在gatsby节点之间创建父/子关系,以便查找可以使用的父节点

const path=require('path'))
exports.onCreateNode=({
节点,
getNodesByType,
行动
}) => {
常数{
createParentChildLink
}=行动
if(node.internal.type==='Directory'){
如果(node.sourceInstanceName=='work'){
//在某些情况下,尾部斜杠缺失。
//始终添加它并规范化路径以删除重复
const parentDirectory=path.normalize(node.dir+'/'))
const parent=getNodesByType('Directory')。查找(
n=>path.normalize(n.absolutePath+'/')==parentDirectory
)
如果(家长){
node.parent=parent.id
createParentChildLink({
子节点:,
家长:家长
})
}
}
}
}
相应的查询可能如下所示:

{
  "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"
            }
          }
        }
      ]
    }
  }
}
{
所有目录(
过滤器:{
sourceInstanceName:{eq:“工作”}
相对目录:{eq:}
}
) {
边缘{
节点{
名称
相对速度
孩子们{
__目录中的typename{
名称
相对速度
}
}
}
}
}
}
输出结果如下所示:

{
“数据”:{
“所有目录”:{
“边缘”:[
{
“节点”:{
“名称”:“图纸”,
“相对路径”:“图纸”,
“儿童”:[
{
“\uuuuTypeName”:“目录”,
“名称”:“图纸1”,
“相对路径”:“图纸/图纸-1”
}
]
}
},
{
“节点”:{
“名称”:“雕塑”,
“相对论”:“雕塑”,
“儿童”:[
{
“\uuuuTypeName”:“目录”,
“姓名”:“Gaehnschrier”,
“relativePath”:“雕塑/雕塑师”
}
]
}
},
{
“节点”:{
“名称”:“水彩画”,
“相对主义”:“水彩画”,
“儿童”:[
{
“\uuuuTypeName”:“目录”,
“名称”:“肖像-1”,
“relativePath”:“水彩/肖像-1”
},
{
“\uuuuTypeName”:“目录”,
“名称”:“肖像-2”,
“relativePath”:“水彩/肖像-2”
}
]
}
}
]
}
}
}

为了便于解释,
\uuuuuuTypeName。。。在目录
上,您可以整体查询相应的节点。否则,您将只获得子节点的ID。为了更好地理解,请访问:

不确定您想要获得什么。您可以包含您试图编写的查询的预期json结果吗?我正在尝试将片段与其对应的父类别进行映射。当这些节点连接(子节点/父节点)时,就有可能在整个树中进行迭代。@CyrilDurand我添加了一个示例,我认为解决方案可能来自
createParentChildLink
:好的,这非常有效。但实际上我想查询完整的节点。那么,如何访问其余的数据呢?现在我只能访问
id
子项
父项
类型名