【问题标题】:Combing related data from two different sources in a single Gatsby page在单个 Gatsby 页面中结合来自两个不同来源的相关数据
【发布时间】:2021-04-11 14:18:12
【问题描述】:

我正在创建一个博客,其中每个博客页面都将使用带有 GPX 路线的传单显示地图。地图下方将是一些统计数据以及一些文本和图像。

我在 mark down 中定义了文本和图像部分,所以我想解决这个问题的方法是在 frontmatter 中定义我的 gpx 文件名,如下所示:

---
title: Awesome Blog Post Title
author: Cancrizan
date: 2021-01-04
gpxFile: activity4835702422
---
BLOG POST here

gpxFile 字段指的是我的项目src/gpx/activity4835702422.gpx 中的一个文件。

我写了一个转换器插件,它将读取 GPX 文件,以便可以像这样查询它:

query MyQuery {
  allActivity4835702422Gpx {
    edges {
      node {
        geometry {
          coordinates
        }
      }
    }
  }
}

并输出如下内容:

{
  "data": {
    "allActivity4835702422Gpx": {
      "edges": [
        {
          "node": {
            "geometry": {
              "coordinates": [
                [
                  -1.2134187016636133,
                  52.92038678191602,
                  29.399999618530273
                ],
                [
                  -1.2134256586432457,
                  52.92039977386594,
                  29.399999618530273
                ],
                ...,
              ]
            }
          }
        }
      ]
    }
  },
  "extensions": {}
}

我想根据 markdown 文件的 frontmatter 访问该节点,但不知道如何?

任何人都可以提出解决方案吗?或者我是否以错误的方式解决这个问题?

【问题讨论】:

    标签: node.js reactjs graphql gatsby


    【解决方案1】:

    您遵循的结构和思维方式完全有效,您唯一缺少的部分是将gpxFile 传递给您的模板,以便基于该参数创建另一个查询。

    您的gatsby-node.js 应该如下所示:

    const path = require("path")
    
    exports.createPages = async ({ graphql, actions, reporter }) => {
      const { createPage } = actions
    
      const result = await graphql(
        `
          {
            allMarkdownRemark(limit: 1000) {
              edges {
                node {
                  frontmatter {
                    title
                    author
                    date
                    gpxFile
                    slug
                  }
                }
              }
            }
          }
        `
      )
    
      if (result.errors) {
        reporter.panicOnBuild(`Error while running GraphQL query.`)
        return
      }
    
      const postTemplate= path.resolve(`src/templates/post.js`);
    
      result.data.allMarkdownRemark.edges.forEach(({ node }) => {
        const path = node.frontmatter.path
        createPage({
           path: `/posts/${node.frontmatter.slug}`,
           component: postTemplate,
           context: {
             gpxFile: node.frontmatter.gpxFile,
             path: node.frontmatter.slug
           }
        })
      })
    }
    

    这个想法是使用上下文 API 将数据(gpxFileDatapath)传递给您的模板(postTemplate),以将其用作您的降价文件的过滤器。

    在您的postTemplate 中,您的查询应如下所示:

    export const postData = graphql`
        query getArticleData($path: String!, $gpxFile: String) {
            post: markdownRemark (fields: {frontmatter: { slug: { eq: $path }}}) {
                html
                excerpt (pruneLength: 350)
                frontmatter {
                  title
                  author
                  date
                  gpxFile
                  slug
                }
            }
            gpxFileData: allFile(relativePath: { in: $gpxFile })
               # your gpx data here
            }
        }
    `;
    

    这是不言自明的,基本上,您通过上下文传递必要的数据,以便从您的gatsby-node.js 在您的模板 (gpxFileData) 中进行查询。在那里,您可以创建一个新查询allFile,通过relativePath 过滤(您可能需要直接访问file 或使用absolutePath,在localhost:8000/___graphql 中测试它)并使用@987654336 检索整个数据@和post.data.gpxFileData

    免责声明:我假设您已正确设置文件系统 (gatsby-source-filesystem) 以在您的 .gpx 文件中使用 allFile

    【讨论】:

    • 感谢 Ferran,您的回答为我指明了正确的方向。正如你所建议的,我已经通过上下文传递了 GPX 文件名,因此它可以用作模板查询中的变量!
    • 我很高兴为@RSmith 提供帮助。如果问题已解决,请考虑接受/投票以关闭问题的答案:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多