GatsbyJs-使用csv中引用的多个图像制作ImageSharp

时间:2020-02-17 04:43:46

标签: gatsby

使用gatsby-transformer-csvgatsby-transformer-sharp

给定一个CSV文件,其中的一个单元格引用了多个图像(具有本地路径),那么如何使它们由imageSharp处理?

id,slug,images
615,prime-click-solid-2,./images/products/PC-019-S1.png, ./images/products/PC-019-S-1.png

2 个答案:

答案 0 :(得分:3)

要使其正常工作,我认为您必须在此处进行大量手动工作。

首先,由于值之间用逗号分隔,因此应将图像分组在一起:

id,slug,images
                         v                        v
615,prime-click-solid-2, "./img-1.png, ./img-2.png"

然后,您可以在gatsby-node中使用createSchemaCustomization钩子来...

  1. 拦截images字段
  2. 从原始值./img-1.png, ./img-2.png
  3. 中提取路径
  4. 为每个图像创建正确的绝对路径
  5. 查询盖茨比数据库中的图像
  6. 返回图像

我有一些停机时间,所以我最终创建了一个小例子。

目录结构:

<root>
  |--content
  |     |
  |     |--images
  |     |     |--img-1.png
  |     |     `--img-2.png
  |     |     
  |     `--data.csv
  |
  `--gatsby-node.js

data.csv内容

id,images
hello,"./images/287.jpg, ./images/288.jpg"

自定义盖茨比钩子

// gatsby-node.js

const path = require('path')

exports.createSchemaCustomization = ({ actions, schema }) => {
  const { createTypes } = actions

  const types = schema.buildObjectType({
    name: 'DataCsv', // Gatsby create name based on your csv file name. Yours will be different — you can find your CSV type name in localhost:8000/___graphql
    interfaces: ['Node'],
    extensions: {
      infer: true,
    },
    fields: {
      images: {
        type: '[File]', // important. We're saying DataCsv.images will return an array of File, instead of a string as inferred by default.
        resolve: async (src, args, context, info) => {
          const { fieldName } = info
          const paths = src[fieldName]
          const imagePaths = paths.split(',').map(str => str.trim())

          const absolutePaths = imagePaths.map(imagePath => {
            return path.join(__dirname, 'content', imagePath)
          })

          const fileNodes = await context.nodeModel.runQuery({
            type: 'File',
            query: {
              filter: {
                absolutePath: {
                  in: absolutePaths
                }
              }
            }
          })

          return fileNodes
        }
      }
    }
  })

  createTypes(types)
}

然后,您可以查询图像:

  query Images {
    dataCsv {
      images {
        childImageSharp {
          original {
            src
          }
        }
      }
    }
  }

您可以在此处查看示例并根据需要进行调整: https://github.com/d4rekanguok/gatsby-csv-multi-images-example

资源

您可以在official docs中了解有关此钩子的更多信息,但这有点干。

我还写了一个教程on the topic here

希望有帮助!

编辑:盖茨比从runQuery开始异步发布(2020年7月),答案已经更新以反映这一点。

答案 1 :(得分:1)

听起来您要在此处进行的操作可以分为两个步骤:

  • 将CSV解析为节点数组,每个节点包含图像URL数组。

  • 在构建时遍历这些节点,并将每个节点的URL数组中的每个URL转换为一个imageSharp节点。


一种处理此 * 的方法是:

    gatsby-config
  • Configure gatsby-transformer-csv为您的CSV节点指定一个自定义名称。

  • onCreateNode中覆盖gatsby-node,添加条件以在创建CSV节点时触发,从该节点提取图像URL数组,并对其进行迭代以创建{{ 1}}文件系统中的节点。

或者,如果您仅解析图像路径,然后将它们传递到具有imageSharp或类似内容的file GraphQL查询中,则可能无需第二步即可完成,如{{ 3}}。请记住,Gatsby中的动态查询只能在顶级“页面”组件中使用,而静态查询则可以在任何地方使用。

* 可能有更好的方法!如上所述,在不了解您的用例的情况下,很难说出“最佳”解决方案是什么。 Gatsby在管理数据方面非常灵活。