如何在整个站点范围内更改 Gatsby post 标题?

How do I change a Gatsby post title site wide?

我希望我的 post 标题是标题大小写。

  1. 它必须是站点范围的(不仅仅是在像 <Helmet> 这样的地方)。我想避免重复和丢失参考的可能性。

  2. 我不想回到我的 post 并更新每一个不是标题大小写的。

有没有办法覆盖frontmatter?我尝试在 gatsby-node.js 中更改它,但我不确定 add/change 在哪里。

我找到了一个我认为是 hack 的解决方案。通过在将节点推送到节点数组之前更新节点,可以在创建节点 onCreateNode 期间覆盖 frontmatter。我利用 postNodes 数组(一个全局数组到 gatsby-node 范围)来创建我的博客页面。

createNodeField({ node, name: "slug", value: slug })
node.frontmatter.title = _.startCase(_.toLower(node.frontmatter.title))
postNodes.push(node)

然后在创建 post 页面时 exports.createPages,使用具有更新值的 postNodes

    let idx = 0;
    postNodes.map(node => {
      let previous = idx - 1 < 0 ? postNodes[postNodes.length - 1] : postNodes[idx - 1]
      let next = idx + 1 >= postNodes.length ? postNodes[0] : postNodes[idx + 1]

      createPage({
        path: node.fields.slug,
        component: postPage,
        context: {
          slug: node.fields.slug,
          prev: previous.fields.slug,
          next: next.fields.slug
        }
      })
      idx += 1;
    })

注意 Prev 和 next 在编写该代码时不起作用,因此需要修改。

刚好需要修改gatsby-transformer-remark修改frontmatter的方式,让我想起了这个问题。你完成它的方式非常好,我只是想提供另一种选择。以下是如何覆盖 frontmatter:

在内部,gatsby-transformer-remark 使用 graymatter 解析 markdown 的 frontmatter(将 md 视为 yaml)。我们可以修改graymatter的默认解析器行为来直接覆盖frontmatter。

// should come with `gatsby-transformer-remark` by default
// if it's missing, install it `yarn add js-yaml`
const yaml = require('js-yaml');

const customParser = (str) => {
  const result = yaml.safeLoad(str);

  // modify `title`. In Gatsby, `title` is guaranteed to exist,
  // but you might want to add a check for other properties.
  if (result.title) {
    result.title = result.title.toUpperCase();
  }
  return result;
}

然后传入gatsby-transformer-remark like

{
  resolve: `gatsby-transformer-remark`,
  options: {
+   engines: {
+     yaml: customParser,
+   },
    plugins: [
      ...
    ],
  },
},

Gatsby查询结果:

{
  "data": {
    "markdownRemark": {
      "frontmatter": {
        "title": "I AM CAPITALIZED"
      }
    }
  }
}