GraphQL静态查询后,Gatsby Markdown FrontMatter链接成为相对文件路径

时间:2020-07-25 13:04:28

标签: javascript reactjs graphql gatsby

我正在尝试存储按钮的内容,该按钮会将用户导航到我的降价记录frontmatter中的其他页面,因为可以通过Netlify CMS对其进行编辑。

当GraphQL静态查询带回数据时,我的首要事项已转换为相对文件路径,而不是预期的页面URL。页面查询不会发生这种情况。

footer.md:

---
templateKey: footer
title: Some footer title
logo: /img/logo.svg
links:
  - url: /prices/
    text: Prices
  - url: /privacy-policy/
    text: Privacy policy
---

GraphQL静态查询:

const queryData = useStaticQuery(graphql`
    query FooterComponent {
      site {
        siteMetadata {
          title
        }
      }
      markdownRemark(frontmatter: { templateKey: { eq: "footer" } }) {
        frontmatter {
          title
          logo {
            publicURL
          }
          links {
            url
            text
          }
        }
      }
    }
  `);

返回的数据:

{
"title":"Some footer title",
"logo":{"publicURL":"/static/6731239d1e0c5fcdf0f825a8de82be10/logo.svg"},
"links":[
    {"url":"../pages/prices","text":"Prices"},
    {"url":"../pages/privacy-policy","text":"Privacy policy"}
  ]
}

您可以看到links数组中对象的URL已转换为相对文件路径,而不是像原始markdown文件一样从frontmatter返回实际链接。

如何获取实际链接?

1 个答案:

答案 0 :(得分:3)

在阅读您对其他答案的评论时,我认为问题出在fmImagesToRelative上。它会跟踪所有已创建的节点,然后尝试将每个frontmatter字段值与所有文件节点的路径进行匹配。

一个快速修复程序可以在运行fmImagesToRelative之前“保留”这些最重要的字段,然后在以后恢复它们。因此,您实际上可以解决该功能,如下所示:

exports.onCreateNode = ({ node }) => {
  const isRemarkNode = node.internal.type === 'MarkdownRemark'
  const originalFields = {}
  if (isRemarkNode) {
    Object.entries(node.frontmatter).forEach(([k, v]) => {
      if (['links', 'some_other_field'].includes(k)) {
        /* preserve */
        originalFields[k] = v
        /* remove the field to avoid unnecessary work */
        delete node.frontmatter[k]
      }
    })
  }

  /* this function won't work without access to literally all nodes, hence why we leave it in the middle like this */
  fmImagesToRelative(node)

  if (isRemarkNode) {
    /* restore */
    node.frontmatter = {
      ...node.frontmatter,
      ...originalFields
    }
  }
}

我个人更喜欢只修改我知道是文件的字段。在您的示例中,我宁愿声明“徽标”为图像文件,而不是排除“链接”。

作为NetlifyCMS的资深用户,我使用createSchemaCustomization来修改已知的文件字段...这相当复杂(与Gatsby一样),所以我写了a plugin来简化这一过程。

所以我的方法如下:


exports.createSchemaCustomization = ({ actions }) => {
  actions.createTypes(`
    type Frontmatter @infer {
      logo: File @fileByAbsolutePath(path: "static")
    }

    type MarkdownRemark implements Node @infer {
      frontmatter: Frontmatter
    }
  `)
}

在上面的示例中,@fileByAbsolutePath是一个字段扩展名,它采用logo值(即img/logo.png)并用static进行解析,因此当您查询降价文件时您将获得一个指向root/static/img/logo.png的文件节点。


fmImagesToRelativeexclude / include个参数将是一件很整洁的事,尽管我不喜欢这种全面的方法。