在 Gatsby.js 中以编程方式创建多种类型的页面

2024-03-28

我正在使用 GatsbyJS 构建一个网站。我在两个不同的文件夹中有 markdown 文件:/content/collections and /content/posts我希望 Gatsby 为每个 Markdown 文件创建一个页面,并使用相应的模板(collection.js 和 post.js)。

所以我在 gatsby-node.js 文件中写了这个:

const path = require('path');
const { createFilePath } = require('gatsby-source-filesystem');
exports.onCreateNode = ({ node, getNode, actions }) => {
  const { createNodeField } = actions;
  if (node.internal.type === 'MarkdownRemark') {
    const longSlug = createFilePath({ node, getNode, basePath: 'content' });
    const slug = longSlug.split('/');
    createNodeField({
      node,
      name: 'slug',
      value: `/${slug[slug.length - 2]}/`,
    });
  }
};

exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions;
  const result = await graphql(`
    query {
      allFile(filter: {relativeDirectory: {eq: "collections"}}) {
        edges {
          node {
            childMarkdownRemark {
              fields {
                slug
              }
            }
          }
        }
      }
    }
  `);
  result.data.allFile.edges.forEach(({ node }) => {
    createPage({
      path: node.childMarkdownRemark.fields.slug,
      component: path.resolve('./src/templates/collection.js'),
      context: {
        slug: node.childMarkdownRemark.fields.slug,
      },
    });
  });
};

exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions;
  const result = await graphql(`
    query {
      allFile(filter: {relativeDirectory: {eq: "posts"}}) {
        edges {
          node {
            childMarkdownRemark {
              fields {
                slug
              }
            }
          }
        }
      }
    }
  `);
  result.data.allFile.edges.forEach(({ node }) => {
    createPage({
      path: node.childMarkdownRemark.fields.slug,
      component: path.resolve('./src/templates/post.js'),
      context: {
        slug: node.childMarkdownRemark.fields.slug,
      },
    });
  });
};

认为这会起作用。它确实适用于我放入的第二种类型。(在这种情况下,它创建帖子,但不创建集合。如果我颠倒调用 createPages 的顺序,它会交换,但它永远不会创建所有这些)

这是我在控制台中收到的错误:

warning The GraphQL query in the non-page component "/Users/matteocarpi/Documents/Web/Ledue/src/templates/collection.js" will not be run.
Exported queries are only executed for Page components. It's possible you're
trying to create pages in your gatsby-node.js and that's failing for some
reason.

If the failing component(s) is a regular component and not intended to be a page
component, you generally want to use a <StaticQuery> (https://gatsbyjs.org/docs/static-query)
instead of exporting a page query.

If you're more experienced with GraphQL, you can also export GraphQL
fragments from components and compose the fragments in the Page component
query and pass data down into the child component — https://graphql.org/learn/queries/#fragments

这两个模板非常相似:

import React from 'react';

import { graphql } from 'gatsby';
import PropTypes from 'prop-types';

const Post = ({data}) => {
  return (
    <div>
      <h1>{data.postData.frontmatter.title}</h1>
    </div>
  );
};

export default Post;

export const query = graphql`
query PostData($slug: String!) {
  postData: markdownRemark(fields: {slug: {eq: $slug}}) {
    frontmatter {
      title
    }
  }
}
`;

Post.propTypes = {
  data: PropTypes.node,
};
import React from 'react';

import { graphql } from 'gatsby';
import PropTypes from 'prop-types';

const Collection = ({data}) => {
  return (
    <div>
      <h1>{data.collectionData.frontmatter.title}</h1>
    </div>
  );
};

export default Collection;

export const query = graphql`
query CollectionData($slug: String!) {
  collectionData: markdownRemark(fields: {slug: {eq: $slug}}) {
    frontmatter {
      title
    }
  }
}
`;

Collection.propTypes = {
  data: PropTypes.node,
};

我尝试重构以下所有 gatsby-node.js 文件这个答案 https://stackoverflow.com/questions/64536170/how-to-create-multiple-page-types-dynamically-in-gatsby-node-js但我最终遇到了同样的情况。

我哪里理解错了?


问题是您用第二个函数声明覆盖了第一个函数声明。有点像这样:

var a = "hello"
a = "world"

相反,您应该执行所有查询并调用createPage对于您想要在单个函数中创建的所有页面,如下所示:

exports.createPages = ({ graphql, actions }) => {
  const { createPage } = actions;

  const collections = graphql(`
    query {
      allFile(filter: {relativeDirectory: {eq: "collections"}}) {
        edges {
          node {
            childMarkdownRemark {
              fields {
                slug
              }
            }
          }
        }
      }
    }
  `).then(result => {
    result.data.allFile.edges.forEach(({ node }) => {
      createPage({
        path: node.childMarkdownRemark.fields.slug,
        component: path.resolve('./src/templates/collection.js'),
        context: {
          slug: node.childMarkdownRemark.fields.slug,
        },
      });
    });
  })

  const posts = graphql(`
    query {
      allFile(filter: {relativeDirectory: {eq: "posts"}}) {
        edges {
          node {
            childMarkdownRemark {
              fields {
                slug
              }
            }
          }
        }
      }
    }
  `).then(result => {
    result.data.allFile.edges.forEach(({ node }) => {
      createPage({
        path: node.childMarkdownRemark.fields.slug,
        component: path.resolve('./src/templates/post.js'),
        context: {
          slug: node.childMarkdownRemark.fields.slug,
        },
      });
    });
  })

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

在 Gatsby.js 中以编程方式创建多种类型的页面 的相关文章

  • 获取单词中重复次数最多的字母的数量

    我正在尝试计算单词中重复次数最多的字母的数量 function GreatestCount str var count for var i 0 i
  • 从 JavaScript 中 Firebase 数据库的查询结果中获取特定子项的值

    我在 Firebase 上有这个示例数据库 样本数据库 我有一个index html 其中有这两个输入文本 div class login form h2 Login Form h2 div
  • 为具有可变内容的内联块元素提供相同的高度?

    我有 4 个宽度固定但内容可变的内联块元素 并且我希望所有这些元素具有相同的高度 最大元素的高度 请参见这个jsfiddle http jsfiddle net kKZXj 我应该如何实现这个目标 如果仅使用 css 无法做到这一点 那么使
  • 从字符串中删除货币符号并使用 Javascript 中的单行转换为数字

    我下面有一个字符串 它是以英镑为单位的价格 我想删除货币符号 然后将其转换为我可以用来与另一个值进行比较的数字 价格 例如 X gt Y 14 50 我之前已将字符串转换为用于货币的数字 var priceNum parseFloat pr
  • 这个特定的 ReactJs 代码是如何执行的初学者问题?

    我是初学者 正在阅读大量代码 现在我想知道下面的代码我明白这段代码在做什么 我需要澄清的是代码流程 当我运行它时 我看到图像正在加载 React 是从上到下执行代码吗 占位符图像异步获得正确的图像 但会App如果需要时间 组件会开始渲染但没
  • 了解执行模型和事件循环

    我读过很多关于JavaScript单线程执行模型 事件循环和事件队列的文章 但有一件事尚不清楚 我创建了一个小提琴来说明我的问题 http jsfiddle net yzpmf67f http jsfiddle net yzpmf67f
  • angular.copy() 和 JSON.parse(JSON.stringify()) 之间的区别?

    有人可以解释 angular copy 和 JSON parse JSON stringify 之间的区别吗 有吗 您会推荐使用什么 angular fromJson angular toJson 与 JSON parse JSON str
  • Atom“自动完成”不起作用

    因此 当您安装 Atom 时 autocomplete 会随其一起提供 并且默认情况下处于启用状态 当我编写代码时 什么也没有显示 为什么 是否需要配置任何文件才能正常工作 In autocomplete plus settings pag
  • Chart.js 没有显示在我的视图中

    我有一个使用 angular js 运行的应用程序 我的视图之一应该加载图表 我正在使用 Chart js 但由于某种原因它不起作用 并且我的控制台上没有显示错误 这是我创建图表的函数 scope writeBatteryChart fun
  • JavaScript 中的常用数字

    在我的任务中 我必须编写一个程序来查找数组中最常见的数字以及它重复的次数 我写了一些东西 但只打印最大重复次数 所以我的问题是如何打印这个元素的值 最大数量 在我的例子中是 4 var array 13 4 1 1 4 2 3 4 4 1
  • 如何滚动到 jQuery Mobile 中的页面元素?

    我有一个很长的 jQuery 移动页面 并且想在页面加载后滚动到该页面中间的元素 到目前为止 我已经尝试了一些事情 最成功的是 jQuery document bind mobileinit function var target if t
  • 使用JS将图像的特定背景颜色设置为透明

    我正在使用以下代码来修改图像的透明度 然而 我想做的只是修改图像的背景颜色并将其 alpha 通道设置为 0 而不是整个图像 以下代码将整个图像的 Alpha 透明度设置为 0 var ctx this data getContext 2d
  • Typeahead.js 干扰 Bootstrap 输入组

    如何防止 Typeahead js 拆分我的 Twitter Bootstrap 3 输入组 每当我将 Typeahead javascript 指向属于输入组一部分的文本区域时 连接的文本区域和提交按钮就会停止连接 这只是 Typeahe
  • 单击窗口后才检测到 keydown

    在我的 Web 应用程序中 我有一个用于打开菜单的键的事件侦听器 仅当我单击页面上的任意位置后 此功能才可以正常工作 我尝试将焦点添加到窗口加载 但这仍然不会让 keydown 函数运行 直到我单击页面上的某个位置之后 有谁知道这是否可能
  • 如何在 svelte 中制作搜索过滤器

    我有两个组件在组件树中距离很远 我对如何在两者之间进行通信存有疑问 我有搜索组件 listItems 和商店 商店 svelte
  • 如何检查摘要周期是否稳定(又名“Angular 完成编译了吗?”)

    tl dr 最初的问题是 如何在每个摘要周期触发回调 但潜在的问题更有趣 因为这回答了两个问题 所以我继续修改了标题 Context 在解决了所有依赖项 nginclude API 调用等之后 我试图控制 Angular 何时完成 HTML
  • 如何修复 AJAX 在选中复选框时始终触发?

    有时这个 AJAX 会触发 有时不会 让我解释一下 habit js document ready function habit check change function habit this parent siblings habit
  • 如何逐步绘制矢量路径? (拉斐尔.js)

    如何逐步动画化矢量路径 就像它被绘制一样 换句话说 慢慢地逐像素地显示路径 我在用着Rapha l js but如果您的答案不是特定于库的 例如可能有一些通用的编程模式可以完成此类事情 我对矢量动画相当陌生 欢迎 使用直线路径很容易做到 就
  • JavaScript 右移负数

    这是片段 var i 101 console log 101 i toString 2 console log 101 gt gt 1 i gt gt 1 toString 2 var l 101 console log 101 l toS
  • 将元素添加到 D3 圆包节点

    我正在尝试制作一个可缩放的圆形包装图 我希望每个子圆圈包含一个较小的图表 该图表始终具有相同的结构 即 4 列 只有条形的高度会改变 我尝试添加一个简单的rect到目前为止我的图表 但矩形没有添加到圆圈中并且是静态的 JS var marg

随机推荐

  • 在 CSS 中使用百分比大小和填充时无法防止嵌套 Div 溢出吗?

    我希望能够使用这些属性来布局嵌套 div width 100 height 100 padding 10px 我希望子元素的宽度和高度是 100 其余的 space after填充是计算出来的 而不是之前计算的 否则 当我有如下例所示的文档
  • Laravel base_path() 给出错误 - 调用未定义的方法 baseDir()

    我有一个测试类 我正在尝试使用全局帮助器方法base path 但我收到以下错误 Error Call to undefined method Illuminate Container Container basePath myprojec
  • AWS API Gateway:使用 302 重定向和 set-cookie 标头

    我使用 AWS API Gateway 进行重定向作为响应 简单流程 aaa com gt API 网关和 Lambda 302 重定向 gt bbb com 跟随时效果很好the blog https rpgreen wordpress
  • 将 JSON 数据从 Android 发送到 PHP 并写入文本文件

    我正在尝试获取在 Android 设备上动态创建的特定 JSON 文件 并使用 HTTP post 请求将该数据发送到 PHP 脚本 以存储到文本文件中以供以后使用 最终我还需要将数据保存在 MySQL 数据库中 但我一次一步地工作 JSO
  • 如何禁用“提交”按钮?

    如何在表单有效之前禁用 提交 按钮 angular2 是否有相当于 ng disabled 的功能 可以在 提交 按钮上使用 ng disabled 对我不起作用 正如这个 Angular 中所见example https github c
  • “签名无效,代码对象根本没有签名”错误

    我已经浏览 Stack 几个小时试图尝试修复这个错误 并且我已经尝试了我能找到 想到的一切 我正在向 App Store 提交现有应用程序的更新 在提交我的版本后 我不断收到此错误 签名无效 代码对象根本没有签名 确保你 已使用分发证书而不
  • 在 Kubernetes pod 中克隆安全的 git 存储库

    我遇到了一个有趣的情况 我需要将私有 github 存储库克隆到我在 Kubernetes 中运行的 Docker 容器中 最初我尝试使用 gitRepo 安装 但是 在我的部署清单中包含 OAuth 密钥是不可接受的 我想使用存储库部署密
  • 避免循环后重复代码?

    使用循环时 我经常会编写两次代码 例如 在复习 Udacity 计算机科学课程时 我编写了代码 用于查找最连续重复的元素的函数 def longest repetition l if not l return None most reps
  • 如何在 Mailjet v3 PHP 包装器中获取联系人 ID?

    我使用 Mailjet api 将提交的电子邮件存储在 Mailjet 列表中 当有 Mailjet 0 1 版本 API 时 这可以正常工作 当时没有任何 PHP 包装器 但很容易使用他们的示例 但是当他们将 API 更改为版本 3 时
  • 使用 ruby​​、python、perl、java 或其他方式对 Google 进行脚本驱动的自动化优化

    背景 同事 Adam 在过去一年左右的时间里一直在使用 Google Refine 来处理数据库下载 并取得了巨大成功 但 Adam 获得了新的工作机会 因此他在 Google Refine 中所做的所有工作和专业知识都将消失 Ben 希望
  • 是否可以将 OpenMP 库与 Android NDK 一起使用?

    是否可以将 OpenMP 库与 Android NDK 一起使用 也许有人已经尝试将它们编译在一起并可以提供一些提示 随着双核平板电脑 智能手机的出现 我认为在应用程序开发中使用 OpenMP 功能会非常好 先感谢您 对于现在遇到这个问题的
  • 导入错误:“图标”未从“antd”导出

    我创建了一个 React 应用程序 并且正在使用 Ant Design antd 在我的一个项目文件中 我想使用该标签 但我不能 显然这是 ANT V4 上的问题 我正在使用以下导入语句 import Icon from antd 并收到以
  • d3.js 在非 svg 元素上强制布局

    d3 js layout force 可以用于 重新 定位 div 等 svg 元素吗 如果 div 有position absolute maybe left and top可以用作等效项x1 and y1用于 svg 元素的属性 目标是
  • 如何将子节点从一个节点复制到另一个节点?

    情况 我需要下载 childNode 然后将其 set 到另一个节点中 问题是我只想在 childNode 的 Score 属性达到 100 时才执行此操作 我应该在何时何地检查帖子的分数是否为 100 或更高 以及如何将它们复制到新索引一
  • jQuery 选择器 jQuery("element") 和 $("element") 有什么区别?

    我以前多次使用过 jQuery 但总是这样使用 document 最近我多次看到有人使用jQuery document 我不知道它们之间的区别 我认为它们是相同的 但我现在有一个非常困难的问题 你知道 jQuery 插件的大部分用途 doc
  • GMSPolyline 非常大的内存峰值

    在允许用户在各种不同类型的地图上显示我们称之为轨迹的复杂位置点列表的 GPS 应用程序中 每个轨迹可以包含 2k 到 10k 个位置点 当轨迹在非 Google 地图类型上呈现时 它们会被大量剪切 修剪和路径简化 这是为了降低内存使用量并提
  • Ubuntu 上的 MonoDevelop 和 libpjsipDll.so 库。系统.DllNotFoundException

    我正在尝试在 Linux 上使用一个名为 libpjsipDll v44 so我从这里得到的http code google com p sipeksdk downloads list http code google com p sipe
  • 使用 strsplit 中长度不等的 ldply

    我正在尝试根据一些分隔符将数据框列拆分为多个列 我在这个网站上找到了各种答案 并且我正在尝试寻找不同的工作方式 我遇到麻烦了ldply 问题是输出strsplit是不同长度元素的列表 这是一些示例数据 有效的数据以及我正在尝试的数据ldpl
  • 哪里可以找到系统调用源代码?

    在 Linux 中 如果我有源代码树 在哪里可以找到所有系统调用的源代码 另外 如果我想查找特定系统调用的源代码和程序集 我可以在终端中输入类似的内容my system call 您需要 Linux 内核源代码才能查看系统调用的实际源代码
  • 在 Gatsby.js 中以编程方式创建多种类型的页面

    我正在使用 GatsbyJS 构建一个网站 我在两个不同的文件夹中有 markdown 文件 content collections and content posts我希望 Gatsby 为每个 Markdown 文件创建一个页面 并使用