使用 GatsbyJS 在 GraphQL 查询中限定文件夹结构
Scoping folder structure in GraphQL Queries with GatsbyJS
我有分类、作品和图片。它们都是级联的;典型的亲子关系。文件夹结构已经代表了这个层次结构。最后我会更详细地解释我的主要问题。
文件夹结构:
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" }
.
查询该文件夹
盖茨比-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
内作品drawing-1
的所有图片。
问题:
在最好的情况下,我想遍历每个类别并显示来自 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
method, in order to find the parent node you can use the getNodesByType
undocumented method 在 gatsby 节点之间创建父/子关系。
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
我有分类、作品和图片。它们都是级联的;典型的亲子关系。文件夹结构已经代表了这个层次结构。最后我会更详细地解释我的主要问题。
文件夹结构:
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" }
.
盖茨比-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
内作品drawing-1
的所有图片。
问题:
在最好的情况下,我想遍历每个类别并显示来自 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
method, in order to find the parent node you can use the getNodesByType
undocumented method 在 gatsby 节点之间创建父/子关系。
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