简体   繁体   English

使用 GatsbyJS 确定 GraphQL 查询中的文件夹结构

[英]Scoping folder structure in GraphQL Queries with GatsbyJS

I do have categories, pieces and pictures.我确实有类别、作品和图片。 They're all in cascading order;它们都是级联顺序; Typical child-parent-relationship.典型的亲子关系。 And the folder structure already represents this hierarchy.文件夹结构已经代表了这个层次结构。 At the end I will explain my main problem in more detail.最后,我将更详细地解释我的主要问题。

Folder structure:文件夹结构:

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

This is a simple hierarchy of a portfolio.这是一个简单的投资组合层次结构。 work is the root folder and has different categories eg drawing . work是根文件夹,有不同的类别,例如drawing Inside you'll find folders, which represent a specific piece.在里面你会找到文件夹,它们代表一个特定的部分。 Each piece has a index.md with detailed information about that piece and multiple images (jpeg, png etc.).每件作品都有一个index.md其中包含有关该作品的详细信息和多个图像(jpeg、png 等)。


gatsby-config.js: gatsby-config.js:

// ...
{
  resolve: 'gatsby-source-filesystem',
  options: {
    name: 'work',
    path: `${__dirname}/work/`,
  },
},
// ...

For resolving the files, I use the gatsby-source-filesystem plugin.为了解析文件,我使用gatsby-source-filesystem插件。 So, I can query that folder by sourceInstanceName: { eq: "work" } .因此,我可以通过sourceInstanceName: { eq: "work" }查询该文件夹。


gatsby-node.js: 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,  
        })
      }
    }
  }
}

This code helps me to flag the categories for later purpose, eg displaying a list of categories on a overview page.此代码帮助我标记类别以供以后使用,例如在概览页面上显示类别列表。


Example Queries:示例查询:

{
  allDirectory(
    filter: {
      sourceInstanceName: { eq: "work" }
      relativeDirectory: { eq: "" }
    }
  ) {
    edges {
      node {
        dir
        name
        extension
        relativeDirectory
        relativePath
      }
    }
  }
}

Querying all categories.查询所有类别。


{
  allDirectory(
    filter: {
      sourceInstanceName: { eq: "work" }
      relativeDirectory: { eq: "drawing" }
    }
  ) {
    edges {
      node {
        dir
        name
        extension
        relativeDirectory
        relativePath
      }
    }
  }
}

Querying all pieces of the category drawing .查询类别drawing所有件。


{
  allFile(
    filter: {
      sourceInstanceName: { eq: "work" }
      extension: { in: ["jpg", "jpeg", "png"] }
        relativeDirectory: { eq: "drawing/drawing-1" }
    }
  ) {
    edges {
      node {
        dir
        name
        extension
        relativeDirectory
        relativePath
      }
    }
  }
}

Querying all pictures of the piece drawing-1 inside category drawing .查询类别drawing中的工件drawing-1所有图片。


The problem:问题:

In the best case I'd like to iterate through each category and display the work pieces with its pictures and descriptions from the index.md .在最好的情况下,我想遍历每个类别并显示带有图片和来自index.md描述的index.md But how can I extract the categories seprately to query for the pieces?但是如何单独提取类别以查询碎片? How should I map these entities together with Gatsby?我应该如何将这些实体与 Gatsby 映射在一起? Is my concept missleading?我的概念是否具有误导性? If you're having any good suggestion, what I should think of to achieve my goal, I'll be very happy with it.如果你有什么好的建议,我应该考虑什么来实现我的目标,我会很高兴的。

EDIT:编辑:

Right now I am fiddling around with sourceNodes() and creating abstract nodes from the folder structure.现在我正在摆弄sourceNodes()并从文件夹结构中创建抽象节点。 The desired JSON could look like this:所需的 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"
            }
          }
        }
      ]
    }
  }
}

You can create parent / child relationship between gatsby node using the createParentChildLink method , in order to find the parent node you can use the getNodesByType undocumented method .您可以使用的盖茨比节点之间的父/子关系createParentChildLink方法,以找到您可以使用父节点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
                })
            }
        }
    }
}

The corresponding query could look like this:相应的查询可能如下所示:

    {
      allDirectory(
        filter: {
          sourceInstanceName: { eq: "work" }
            relativeDirectory: { eq: "" }
        }
      ) {
        edges {
          node {
            name
            relativePath
            children {
              __typename ... on Directory {
                name
                relativePath
              }
            }
          }
        }
      }
    }

And the output would look like:输出将如下所示:

    {
      "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"
                  }
                ]
              }
            }
          ]
        }
      }
    }

For explanation, __typename ... on Directory gives you the opportunity to query the corresponding node as a whole.为了说明, __typename ... on Directory使您有机会从整体上查询相应的节点。 Otherwise you'll get only the ID of the child node.否则,您将只获得子节点的 ID。 For better understanding visit: https://graphql.org/learn/schema/#union-types为了更好地理解,请访问: https : //graphql.org/learn/schema/#union-types

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM