连接两个 gatsby 节点

2023-11-25

所以,我正在使用盖茨比 mdx用于从 MDX 文件创建站点的插件。我想在 SitePage 对象和 Mdx 对象之间创建关联,以便我可以对 SitePage 边缘执行一个 graphQL 查询来构建站点导航。

我的大部分代码都是用 TypeScript 编写的,所以如果你想知道这些是什么 WTF,请忽略任何类型注释。

我尝试过的事情

使用字段

我的第一个想法是使用onCreateNodeAPI,获取 MDX 节点,然后使用以下命令将其添加到 SitePagecreateNodeField行动。一切都很好,B-U-T gatsby-mdx 插件添加一堆其他信息到他们的节点稍后使用setFieldsOnGraphQLNodeTypeAPI(发生after the onCreateNode应用程序编程接口)。我希望这些字段(例如 frontmatter 和 tableOfContents)在以后的 graphql 查询中可用,但他们没有使用此方法。

实施我自己的setFieldsOnGraphQLNodeType

我想我可以像 gatsby-mdx 扩展 Mdx 节点一样扩展 SitePage 对象。

我在这里遇到的关键问题是我无法弄清楚如何创建 Mdx GraphQL 节点类型。

export const setFieldsOnGraphQLNodeType = ({type, actions, getNodes}: any, pluginOptions: any) => {
    if (type.name === "SitePage") {
        const {createParentChildLink} = actions
        return new Promise((resolve) => {
            return resolve({
                "childMdx": {
                    type: new GraphQLObjectType({
                        name: 'Mdx'
                    }),
                    async resolve(sitePageNode: any) {
                        const allNodes = getNodes()
                        if (sitePageNode.component &&
                            (sitePageNode.component.endsWith(".mdx") || sitePageNode.component === DefaultLayout)
                        ) {
                            const associatedMdx = allNodes.find((mdxNode: any) =>
                                mdxNode.internal.type === 'Mdx' && mdxNode.fileAbsolutePath === sitePageNode.component
                            )
                            if (associatedMdx) {
                                console.log("Found associated MDX node", associatedMdx.id)
                                console.log("Adding it to the sitepage node", sitePageNode.id)
                                return associatedMdx
                            }
                        }
                    }
                }
            })
        })
    }
    return {}
}

我还尝试简单地将类型作为字符串('Mdx')传递,但这也失败了。

使用父子链接

该插件在 File 节点和解析的 MDX 节点之间创建父子链接onCreateNodeAPI,使用创建父子链接行动 (source).

我尝试实施...

export const onCreateNode = ({node, actions, getNodes}: OnCreateNodeArgument) => {
    const {createParentChildLink} = actions
    const allNodes = getNodes()
    if (node.internal && node.internal.type === 'SitePage' && node.component &&
        (node.component.endsWith(".mdx") || node.component === DefaultLayout)
    ) {
        const associatedMdx = allNodes.find((mdxNode: any) =>
            mdxNode && mdxNode.internal && mdxNode.internal.type === 'Mdx' &&
                (mdxNode.fileAbsolutePath === node.component || mdxNode.fileAbsolutePath === node.context.fileAbsolutePath)
        )
        if (associatedMdx) {
            console.log("Found associated MDX node", associatedMdx.id)
            console.log("Adding it to the sitepage node as a child", node.id)
            createParentChildLink({parent: node, child: associatedMdx})
        }
    }
}

起初,这似乎成功了,但tableOfContents财产gatsby-mdx 添加到 Mdx 节点的信息在 graphQL 查询中仍然不可用,例如:

{
    allSitePage(filter: {fields: {childMdx: {id: {ne: null}}}}) {
        edges {
            node {
                path
                fields{
                    childMdx {
                        tableOfContents
                        fileAbsolutePath
                        frontmatter {
                            title
                        }
                    }
                }
                context {
                    roughFilePath
                    id
                }
            }
        }
    }
}

其他(可能不相关)信息

I'm 以编程方式创建一些页面在 gatsby-node.js 中。

我看到了类似用例的建议节点类型映射,但由于 SitePage 和 MDX 对象之间的映射需要一些技巧(具体来说,从 siteMetadata 读取一些内容并进行字符串比较),我认为这不适用于我的用例。


所以我终于找到了一个更好的解决方案(比我之前的尝试,其中涉及将 mdx 节点泵入页面的context).

盖茨比有一个未记录的方法将节点相互链接:

是的,您可以使用 createNodeField 和尚未记录的 ___NODE 语法来创建节点之间的链接。

所以,步骤是这样的:

  • In createPage,存储idMdx 节点到 SitePage 节点。
  • In onCreateNode,如果节点是SitePage, use createNodeFieldMdx___NODE作为字段名称,Mdx 节点的 id 作为值。

My gatsby-node.js:

const path = require("path")
const { createFilePath } = require("gatsby-source-filesystem")

exports.onCreateNode = ({ node, actions, getNode }) => {
  const { createNodeField } = actions

  if (node.internal.type === "SitePage" && node.context && node.context.id) {

    createNodeField({
      name: "Mdx___NODE",
      value: node.context.id,
      node,
    })
  }

  if (node.internal.type === "Mdx") {
    const value = createFilePath({ node, getNode })
    createNodeField({
      // 1) this is the name of the field you are adding,
      name: "slug",
      // 2) this node refers to each individual MDX
      node,
      value: `/blog${value}`
    })
  }
}


exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions;
  const { data, errors } = await graphql(`
    {
      allMdx {
        edges {
          node {
            id
            fields {
              slug
            }
          }
        }
      }
    }
  `)

  if (errors) throw errors
  data.allMdx.edges.forEach(({ node }) => {
    createPage({
      path: node.fields.slug,
      component: path.resolve(`./src/components/posts-page-layout.js`),
      context: { id: node.id }
    });
  });
};

Result:

graphiql

希望能帮助到你!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

连接两个 gatsby 节点 的相关文章

随机推荐

  • iOS 未收到通过 API 发送的 Firebase 推送通知

    我正在使用 Google 的 Firebase Cloud Messaging 将推送通知发送到我的 iOS 和 Android 应用程序 通过云消息控制台发送的推送通知按预期工作 但是当我通过 API 发送推送通知时 iOS 应用程序仅在
  • jquery:在图像后淡入淡出

    我有一个包含 10 张图像的页面 我想在图像下载后将它们逐个淡入淡出 如何检测图像已加载并准备好显示 我应该循环加载加载的图像 fadeIn 并一旦 fadeIn 等待下一个加载吗 只需在图像上使用 load 事件即可 例如 some im
  • 重写方法上的 Java Class.getMethods() 行为

    在使用 Java 反射编写一个简单的 JSON 序列化程序时 我对 Class getMethods 的行为感到措手不及 如果重写方法的返回类型扩展了被重写方法的返回类型 则 Java Class getMethods 似乎会返回重写方法和
  • 如何使用 Apache Batik 将一张 SVG 图像叠加到另一张 SVG 图像上?

    我有 2 个 SVG 文件需要使用 Batik 进行叠加 第一个文件用作背景图像 大小为 308 像素 x 308 像素 而第二个文件 260 像素 x 260 像素 是必须居中的前景图像 即位于背景图像的中心 我希望将操作结果保存在第三个
  • 为什么全局匿名联合需要声明为静态?

    C 0x 草案 9 5 6 在命名命名空间或全局命名空间中声明的匿名联合应声明为静态的 为什么是这样 假设匿名联合不需要声明为静态 并且编译器遇到这两个翻译单元 预处理后 File1 union int a char b Further c
  • Microsoft Visual Studio:opendir() 和 readdir(),如何实现?

    我之前在我的 Dev cpp 中使用过这种代码 if dh opendir folder false while file readdir dh false do my stuff closedir dh 但现在我正在使用 MSVC 我不知
  • CSS边框颜色分为4种颜色

    有什么方法可以让 CSS 边框的一侧有 4 种不同的颜色吗 我目前有 header border color 88a9eb 我想要有 4 种纯色边框 每种颜色有 25 的分割 这可能吗 我想制作一个完整的版本 中间没有白色的部分 您可以使用
  • 如何从另一个 job2 访问 Hudson job1 工件?

    我们在哈德逊的一个项目中有一份制作工作和一份夜间工作 生产作业需要从特定的夜间构建 作为参数提供 中提取一些工件 谁能帮助我们提示如何实现这一目标 The 复制神器插件似乎能够做到这一点 另一种方法可能是通过获取工件 http server
  • 在 Selenium Chrome 驱动程序中禁用缓存

    我使用 Selenium ChromeDriver 来测量网页的性能 但默认情况下 Chrome 驱动程序缓存是启用的 Option disable application cache现已弃用https code google com p
  • std::mutex 作为类成员,并将类对象存储到容器中

    下面是重现该错误的最少代码 include
  • Powershell:查找/替换 ASCII 控制字符的模式

    我正在尝试编写一个脚本来搜索文件的内容 并在遇到一组 ASCII 控制字符时插入 CR LF 我想替换的字符模式是 ETX NUL STX ETX SOH filenames Get Childitem E VendorFiles CR c
  • Resharper 8.1 测试运行器减慢 Visual Studio 文本编辑速度

    我有一个相当小的 C 解决方案 其中包含大约 5 个项目 我正在使用带有 Update 4 的 Visual Studio 2012 和 Resharper 8 1 内部版本 8 1 23 546 它采用配备 SSD 和 16GB RAM
  • Ruby on Rails 多态关系的优点和缺点 [关闭]

    Closed 这个问题需要多问focused 目前不接受答案 您知道 Ruby on Rails 多态关系有哪些优点和缺点 优点 您可以轻松地将任何东西链接到任何东西 适应性强的关系有助于适应不可预见的情况 很容易建立关系 非常适合临时系统
  • 如何使用 from_json 和 schema 作为字符串(即 JSON 编码的 schema)?

    我正在从 Kafka 读取一个流 并将 Kafka 的值 即 JSON 转换为 Structure from json有一个采用类型模式的变体String 但我找不到样本 请指出下面的代码有什么问题 Error Exception in t
  • Jboss 在根上下文中部署

    是的 我知道enable welcome root false 但在文件中找不到这个 使用 Wildfly Final 或 jboss eap 6 2 在哪儿 为什么我需要在 WEB INF 中添加 jboss web xml 有问题的文件
  • “@Transactional”应该放在服务层或 DAO 的哪里

    首先 我可能正在问一些以前被问过并回答过的问题 但我无法返回搜索结果 我们在服务层定义事务注释 典型的 Spring Hibernate CRUD 通常是 控制器 gt 管理器 gt Dao gt Orm 我现在遇到的情况是 我需要根据客户
  • 在谷歌地图android上实现落针动画

    我正在我的 Android 应用程序中实现谷歌地图 在此过程中我想添加落针动画 我已经搜索了所有内容 但找不到执行此操作的确切方法 任何人都可以帮助我如何做 这将是一个很大的帮助 将标记添加到地图中的所需位置 然后使用该标记调用此函数 pr
  • Python - PyQt - QTable Widget - 添加行

    我是 PyQt 的新手 无论如何仍然有点困惑 我有一个像这样的文本文件结构 姓名 姓氏 电话 电子邮件 空格实际上是制表符 t 现在当我用我的方法读取这个文件时 我希望填充 QTableWidget 我的 QTable Widget 有 4
  • C Int 和 Long 32 - 64 位中的值范围

    我对 C 中 Int 变量的值范围感到困惑 我知道 32 位 unsigned int 的范围是 0 到 65 535 那么只要有0到4 294 967 295 这在 32 位机器上没问题 但现在在 64 位机器中一切都保持不变吗 或者也许
  • 连接两个 gatsby 节点

    所以 我正在使用盖茨比 mdx用于从 MDX 文件创建站点的插件 我想在 SitePage 对象和 Mdx 对象之间创建关联 以便我可以对 SitePage 边缘执行一个 graphQL 查询来构建站点导航 我的大部分代码都是用 TypeS