在graphql查询返回后,盖茨比获得图片路径

时间:2019-01-15 19:19:57

标签: reactjs graphql gatsby

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

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

这确实非常有效,使我能够进行类似/category-name/article-name的路径。

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

到目前为止,我已经成功地通过将以下内容添加到“ 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数据范围内一直有效,现在我看到以下内容:

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

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

我认为我需要对this SO question做一些回答,但这似乎希望您知道relativePath是在您编写查询时,但是我没有该信息,直到查询第一次返回为止。

添加了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,
    })
  }
}

1 个答案:

答案 0 :(得分:1)

我意识到我以前的答案是错误的,并且过于复杂(它依赖于节点创建顺序,也不需要向imageSharp节点添加字段。如果有人感兴趣,这里是the link。)这是更好的答案:

使用mardown在同一文件夹中查询hero名称的图像

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

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

Graphql查询:

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

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

中获得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>
      )
    }

这里是the gist for article.js and gatsby-node.js.