【问题标题】:Gatsby markdown frontmatter link becomes a relative file path after GraphQL static queryGatsby markdown frontmatter 链接变成 GraphQL 静态查询后的相对文件路径
【发布时间】:2020-11-15 05:03:24
【问题描述】:

我正在尝试在我的 markdown frontmatter 中存储一个按钮的内容,该按钮会将用户导航到不同的页面,因为它可以通过 Netlify CMS 进行编辑。

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

页脚.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 返回实际链接。

如何检索实际链接?

【问题讨论】:

    标签: javascript reactjs graphql gatsby


    【解决方案1】:

    阅读您对另一个答案的评论,我认为问题在于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 参数会很好,尽管我不喜欢一揽子方法。

    【讨论】:

    • 似乎很疯狂,需要解决这个问题!我原以为通过 CMS/frontmatter 管理页面链接是一种常见需求
    猜你喜欢
    • 2019-06-12
    • 2019-01-23
    • 2019-04-24
    • 2020-10-22
    • 2020-02-15
    • 2018-07-11
    • 2020-08-07
    • 1970-01-01
    • 2020-09-10
    相关资源
    最近更新 更多