Gatsby在graphql查询返回后获取图像路径 [英] Gatsby getting image path after graphql query has returned

查看:127
本文介绍了Gatsby在graphql查询返回后获取图像路径的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我在Gatsby和Remark上写了一个博客网站.我的帖子结构如下:

So I've written a blog site in Gatsby and Remark. I've structured my posts like this:

Library/
 -- category-name/
 ---- article-name/
 ------ index.md

这确实非常有效,并且使我能够像/category-name/article-name那样制作路径.

This has worked really well and results in me being able to make paths like /category-name/article-name.

我还想做的是能够在其中放置一个名为"hero.jpg"的图像,并让盖茨比自动将其拾取,而不必为其添加前题参考.

What I also would like to do is to be able to drop an image in there called 'hero.jpg' and for it to be automatically picked up by Gatsby without having to add a frontmatter reference to it.

到目前为止,我已经设法通过将以下内容添加到"gatsby-node.js"中来做到这一点:

I've managed to get so far by adding the following to 'gatsby-node.js':

const hero = (fs.existsSync(path.resolve(__dirname, `src/library/pages/${slug}hero.jpg`))) ? `${slug}hero.jpg` : ''
createNodeField({
      node,
      name: 'hero',
      value: hero,
    })

这在graphql数据范围内一直有效,现在我看到以下内容:

This works as far as the graphql data goes and I now see the following:

{
  "node": {
  "id": "3190922a-2207-5621-a7be-e02be9e8da24",
  "fields": {
    "hero": "/category-name/article-name/hero.jpg"
  },
},

但是,在实际页面上,图像链接/category-name/article-name/hero.jpg不存在,所以我得到了无效的图像.我知道这是因为我的图像路径正在被gatsby-transformer-sharp转换,但是我不知道如何确定它要转换为什么.

However on the actual page, the image link /category-name/article-name/hero.jpg doesn't exist so I get a dead image. I know this is because my image path is being transformed by gatsby-transformer-sharp but I don't know how to work out what it is being transformed to.

我认为我需要对这个问题进行解答,但似乎希望您知道relativePath是在编写查询时,但是直到查询第一次返回后,我才拥有该信息.

I believe I need to do something akin to the answers on this SO question but that seems to expect you to know that the relativePath is at the time you are writing your query but I won't have that information until after the query has returned the first time.

添加了OnCreateNode钩子以实现清晰性


exports.onCreateNode = ({ node, getNode, actions }) => {
  const { createNodeField } = actions
  // Add slug to MarkdownRemark node
  if (node.internal.type === 'MarkdownRemark') {
    const slug = createFilePath({ node, getNode, basePath: 'library' })
    const hero = (fs.existsSync(path.resolve(__dirname, `src/library/pages/${slug}hero.jpg`))) ? './hero.jpg' : ''

    createNodeField({
      node,
      name: 'slug',
      value: slug,
    })
    createNodeField({
      node,
      name: 'hero',
      value: hero,
    })
  }
}

推荐答案

我意识到我之前的回答不正确&过于复杂(它依赖于节点创建顺序,也无需向imageSharp节点添加字段.如果某人的链接是链接,则为链接感兴趣的.).这是更好的答案:

I realized my previous answer was incorrect & overly complicated (It relies on node creation order, also there's no need to add fields to imageSharp nodes. Here's the link if someone's interested.). Here's the better answer:

由于英雄图片始终与降价文件位于同一目录中,因此我们只需根据其目录进行查询即可.

Since the hero image is always at the same directory as the markdown file, we can simply query it based on its directory.

            dir              name  ext
┌────────────┴────────────┐ ┌─┴─┐ ┌─┴─┐
absolute/path/to/directory/ hero  .png
absolute/path/to/directory/ index .md

Graphql查询:

Graphql query:

file ( dir: { eq: "absolute/path/to/directory" }, name: { "hero" } ) {
  childImageSharp {
    fixed {
      src
    }
  }
}

您需要对gatsby-node.js进行的唯一修改是将此dir字段添加到页面的context中,以便我们将其用作变量. 我们可以通过执行path.parse(node.fileAbsolutePath).dir来获得dir,或者从备注的父节点getNode(node.parent.id).dir

The only modification you need to make to your gatsby-node.js is to add this dir field to your page's context so we can use it as a variable. We can get this dir by doing path.parse(node.fileAbsolutePath).dir, or get the dir field from remark's parent node getNode(node.parent.id).dir

   +  const { dir } = getNode(node.parent.id)

      createPage({
        path: node.fields.slug,
        component,
        context: {
   +      dir,
          slug: node.fields.slug,
        },
      })

并像这样查询它:

    export const pageQuery = graphql`
   -  query ArticleByPath($slug: String!) {
   +  query ArticleByPath($slug: String!, $dir: String!) {
        markdownRemark(fields: { slug: { eq: $slug } }) {
          id
          htmlAst
          frontmatter {
            title
          }
        }
   +    file (dir: { eq: $dir }, name: { eq: "hero" }) {
   +      childImageSharp {
   +        fixed {
   +          src
   +        }
   +      }
   +    }
      }
    `

并使用它:

    export default function Template({ data }) {
      const post = data.markdownRemark
  +   const hero = data.file ? data.file.childImageSharp : null
      return (
        <div className="landing-page-container">
          <Helmet title={`Your Blog Name - ${post.frontmatter.title}`} />
          <div className="blog-post">
  +         {hero && <img src={hero.fixed.src} alt={post.frontmatter.title} />}
            <h1>{post.frontmatter.title}</h1>
            <div className="blog-post-content">{renderAst(post.htmlAst)}</div>
          </div>
        </div>
      )
    }

这是 article.jsgatsby-node.js的要旨.

Here's the gist for article.js and gatsby-node.js.

这篇关于Gatsby在graphql查询返回后获取图像路径的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆