如何使用 Graphql 从 Strapi 查询 Gatsby 中的多个图像

Posted

技术标签:

【中文标题】如何使用 Graphql 从 Strapi 查询 Gatsby 中的多个图像【英文标题】:How to query multiple images in Gatsby from Strapi using Graphql 【发布时间】:2020-10-25 23:02:02 【问题描述】:

我在 Strapi 上的项目内容类型上设置了一个名为图片的多媒体(图像)字段,并且我添加了 2 个项目,每个项目的图片包含 4 个图像。 我想在 Gatsby 中使用 Graphql 查询这些图像。

这是我在 gatsby-config.js 中的插件数组

    plugins: [
    `gatsby-plugin-react-helmet`,
    
      resolve: `gatsby-source-filesystem`,
      options: 
        name: `images`,
        path: `$__dirname/src/images`,
      ,
    ,
    `gatsby-plugin-sharp`,
    `gatsby-transformer-sharp`,
    
      resolve: `gatsby-plugin-manifest`,
      options: 
        name: `gatsby-starter-default`,
        short_name: `starter`,
        start_url: `/`,
        background_color: `#663399`,
        theme_color: `#663399`,
        display: `minimal-ui`,
        icon: `src/images/gatsby-icon.png`,
      ,
    ,
    
      resolve: `gatsby-source-strapi`,
      options: 
        apiURL: `http://localhost:1337`,
        queryLimit: 1000,
        contentTypes: [`project`],
      ,
    ]

这是我在 localhost:8000/___graphql 上的 graphql 查询

query MyQuery 
  allStrapiProject 
    nodes 
      pictures 
        formats 
          thumbnail 
            childImageSharp 
              fluid 
                src
              
            
          
        
      
    
  

这是我得到的结果

   
  "data": 
    "allStrapiProject": 
      "nodes": [
        
          "pictures": [
            
              "formats": 
                "thumbnail": null
              
            ,
            
              "formats": 
                "thumbnail": 
                  "childImageSharp": 
                    "fluid": 
                      "src": "/static/eb8a7ee6108ecc0e6185aced82c3316b/b4216/167f320a448c2d6ff65acf179ee627e2.jpg"
                    
                  
                
              
            ,
            
              "formats": 
                "thumbnail": null
              
            ,
            
              "formats": 
                "thumbnail": null
              
            
          ]
        ,
        
          "pictures": [
            
              "formats": 
                "thumbnail": null
              
            ,
            
              "formats": 
                "thumbnail": null
              
            ,
            
              "formats": 
                "thumbnail": null
              
            ,
            
              "formats": 
                "thumbnail": null
              
            
          ]
        
      ]
    
  

除一个外,所有缩略图都包含 null。

我曾尝试运行“gatsby clean”,有时即使我在 Strapi 上没有重复图像,也会让查询输出在多个位置具有相同的图像 URL。

【问题讨论】:

【参考方案1】:

到目前为止,还没有“官方”的方式来实现它。但是有一种解决方法可以在构建过程中创建一个自定义节点。对于如下所示的 graphql 查询

query MyQuery 
  allStrapiPortfolio 
    edges 
      node 
        category 
          images 
            localFile 
              childImageSharp 
                fluid 
                  base64
                  tracedSVG
                  srcWebp
                  srcSetWebp
                  originalImg
                  originalName
                
              
            
          
        
      
    
  


下面给出的代码在images 之后创建localFile 节点。代码应该放在gatsby-node.js

const  createRemoteFileNode  = require(`gatsby-source-filesystem`);

exports.onCreateNode = async ( node, actions, store, cache ) => 
  const  createNode, createNodeField  = actions;

  if (node.internal.type !== null && node.internal.type === "StrapiPortfolio") 
    for (const category of node.category) 
      for (const image of category.images) 
        console.log(image);
        const fileNode = await createRemoteFileNode(
          url: "http://localhost:1337" + image.url,
          store,
          cache,
          createNode,
          createNodeId: (id) => image.id.toString(),
        );

        if (fileNode) 
          image.localFile___NODE = fileNode.id;
        
      
    
  
;

请注意,您必须根据需要自定义代码。在我的解决方案中,由于我的数据结构,我使用了两个 for 循环。如果您不确定或只是想检查您的自定义代码是否有效,您可以简单地在第一个 if 语句之前添加一个 console.log(node) 并在第二个 for 循环之后添加一个 console.log(image)(在我的情况下)。这应该会给你一个关于你的数据结构以及你应该以何种方式进行的指示。

【讨论】:

【参考方案2】:

你需要创建一个localFile___NODE。

首先,您需要编辑 gatsby-node.js 文件。

const  createRemoteFileNode  = require(`gatsby-source-filesystem`)
exports.onCreateNode = async (
 node,
 actions,
 store,
 cache,
 createNodeId,
) => 
const  createNode  = actions

// replace ".sliderHome" for the name of multiple media in Strapi CMS
let sliderImages = node.sliderHome

// replace “StrapiHome” for your node type

if (node.internal.type === "StrapiHome") 
  if (sliderImages.length > 0) 
    // sliderImages.forEach(el => console.log(el))
    const images = await Promise.all(
      sliderImages.map(el =>
        createRemoteFileNode(
          url: `http://localhost:1337$el.url`,
          parentNodeId: node.id,
          store,
          cache,
          createNode,
          createNodeId,
        )
       )
     )

    sliderImages.forEach((image, i) => 
      image.localFile___NODE = images[i].id
    )
   
 

稍后重新启动 Gatsby,现在这是您的查询

query MyQuery 
  allStrapiProject 
    nodes 
      pictures 
        localFile
          childImageSharp
            fluid(maxWidth: 1200)
              // or for gatsby use ...GatsbyImageSharpFluid_withWebp
              src 
            
          
        
      
    
  

这对我来说可以带来多张高质量的图像,我希望它对你有用

【讨论】:

【参考方案3】:

试试下面,替换你需要显示的值: 这里我以用户头像为例

query MyQuery 
  allStrapiUser 
      edges 
        node 
          id
          avatar 
            publicURL
            childImageSharp 
              fluid 
              src
              aspectRatio
              
            
          
        
      
    

和: const poster = data.allStrapiUser.edges[0].node

<Img fluid=aspectRatio: 1.6, src: poster.avatar.publicURL/>

【讨论】:

以上是关于如何使用 Graphql 从 Strapi 查询 Gatsby 中的多个图像的主要内容,如果未能解决你的问题,请参考以下文章

Strapi - 如何使用自定义属性扩展 graphql 类型模式?

Gatsby GraphQL 无法在 Strapi 的“文件”类型上查询字段“url”

Strapi中graphql的多个无用的mysql查询

获取 Strapi GraphQL 查询中的图像格式

如何将strapi、graphql和postgres连接在一起?

GraphQL / Strapi - 无法按字符串字段过滤