Gatsby 内容丰富的嵌入图像

gat*_*bie 6 contentful graphql gatsby gatsby-image raw

正如我所看到的,当仅查询 contentfulBlogPost 原始数据时,不再有 json 选项。我能够进行一些更改以获取身体中的所有内容,除了该帖子中的图像。

如果我在 GraphQL Playground 中进行测试,我可以获得图像 id 和 url,但仅此而已。

query {
  allContentfulAsset {
    edges {
      node {
        id
        file {
          url
        }
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

我试图找到一个如何获取嵌入图像的示例,但没有运气......

import React from 'react'
import { graphql } from 'gatsby'
import { documentToReactComponents } from '@contentful/rich-text-react-renderer'

import Layout from '../components/layout'


export const query = graphql`
  query($slug: String!) {
    contentfulBlogPost(slug: {eq: $slug}) {
      title
      publishedDate(formatString: "MMMM Do, YYYY")
      body {
        raw 
      }
    }
    allContentfulAsset {
      edges {
        node {
          id
          file {
            url
          }
        }
      }
    }
  }
`

const Blog = (props) => {
  const options = {
    renderNode: {
      "embedded-asset-block": (node) => {
        const alt = node.data.title
        const url = node.file.url
        return <img alt={alt} src={url}/>
      }
    }
  }
  return (
        <Layout>
          <h1>{props.data.contentfulBlogPost.title}</h1>
          <p>{props.data.contentfulBlogPost.publishedDate}</p>
          {documentToReactComponents(JSON.parse(props.data.contentfulBlogPost.body.raw, options))}
        </Layout>
    )
}

export default Blog
Run Code Online (Sandbox Code Playgroud)

插件:

...
 'gatsby-plugin-sharp',
    {
      resolve:   'gatsby-transformer-remark',
      options: {
        plugins: [
          'gatsby-remark-relative-images',
          {
            resolve: 'gatsby-remark-images-contentful',
            options: {
              maxWidth: 750,
              linkImagesToOriginal: false
            }
          }
        ]
      }

    }
  ],
}
Run Code Online (Sandbox Code Playgroud)

小智 6

您好,我在 Youtube 评论中看到了这个解决方案。您要做的第一件事是将 Graphql 查询更改为如下所示:

    query ($slug: String!) {
      contentfulBlogPost(slug: {eq: $slug}) {
         id
         title
         publishedDate(formatString: "MMMM Do, YYYY")
         body {
            raw
            references {
               ... on ContentfulAsset {
                  contentful_id
                  title
                  file {
                     url
                  }
               }
            }
         }
      }
   }
Run Code Online (Sandbox Code Playgroud)

然后将options常数更改为:

    const options = {
      renderNode: {
         [BLOCKS.EMBEDDED_ASSET]: node => {
            console.log(node);
            const imageID = node.data.target.sys.id;
            const {
               file: {url}, 
               title
            } = props.data.contentfulBlogPost.body.references.find(({contentful_id: id}) => id === imageID);

            return <img src={url} alt={title} />
         }
      }
   }
Run Code Online (Sandbox Code Playgroud)


Fer*_*reu 1

使用类似的东西:

\n
import { BLOCKS, MARKS } from "@contentful/rich-text-types"\nimport { renderRichText } from "gatsby-source-contentful/rich-text"\n\xe2\x80\x8b\nconst Bold = ({ children }) => <span className="bold">{children}</span>\nconst Text = ({ children }) => <p className="align-center">{children}</p>\n\xe2\x80\x8b\nconst options = {\n  renderMark: {\n    [MARKS.BOLD]: text => <Bold>{text}</Bold>,\n  },\n  renderNode: {\n    [BLOCKS.PARAGRAPH]: (node, children) => <Text>{children}</Text>,\n    [BLOCKS.EMBEDDED_ASSET]: node => {\n      return (\n        <>\n          <h2>Embedded Asset</h2>\n          <pre>\n            <code>{JSON.stringify(node, null, 2)}</code>\n          </pre>\n        </>\n      )\n    },\n  },\n}\n\xe2\x80\x8b\nrenderRichText(node.bodyRichText, options)\n
Run Code Online (Sandbox Code Playgroud)\n

资料来源:https ://www.contentful.com/developers/docs/tutorials/general/rich-text-and-gatsby/

\n

return条目中的声明将BLOCKS.EMBEDDED_ASSET包含您的数据,适应您的需求。如果您进入依赖项,您将看到所有公开的方法,因此您还将有一个BLOCKS.EMBEDDED_ENTRY用于嵌入条目的条目。像这样应用它:

\n
[BLOCKS.EMBEDDED_ENTRY]: node => {\n  // your logic to manipulate the entry here\n  return (\n    <>\n      <div>whatever</div>\n    </>\n  )\n},\n
Run Code Online (Sandbox Code Playgroud)\n