首页 > 解决方案 > 从 Gatsby URL slug 中删除发布日期

问题描述

我们有一个 Gatsby 博客,其文件夹结构与此类似content/blog/bees-are-dying/index.mdx。我们的博客不断增长,文件夹变得杂乱无章,这就是我们希望在文件夹名称中包含日期的原因。因此,bees-are-dying我们将文件夹命名为20210309-bees-are-dying.

但是,我们不希望日期出现在 slug 中。URL 应保持为www.web.com/blog/bees-are-dying. 更复杂的是,并非所有文件夹都会在文件夹名称中包含日期......

如何在 Gastby 3 中进行设置?

干杯!


相关问题希望以相反的方式执行此操作,并将日期添加到 slug ( 1 ),从 slug ( 2 )中删除父文件夹名称或在非 Gatsby 环境中删除固定长度的前缀 ( 3 )。

标签: gatsbyslug

解决方案


解决了gatsby-node.js通过检查文件中 slug 的开头是否存在八位数字 (YYYYMMDD) 。使用此代码段:

    /* gatsby-node.js */
    
    let slug = createFilePath({ node, getNode, basePath: `pages` })
    console.log(slug)

    if (!isNaN(slug.substring(1, 9))) {
        slug = slug.replace(slug.substring(1, 10), "");
        console.log("removed date. new slug: " + slug);
    }

我确信有更好的方法来做到这一点。这仅检查数字是否为数字,不验证数字是否为日期。它还假定要删除尾随连字符。请注意,这与问题中提到的文件夹结构不匹配,而是与Gatsby Tutorialpages/bees-are-dying.mdx中使用的基本结构不匹配。


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 fileNode = getNode(node.parent)
    console.log(`\n`, fileNode.relativePath)

    let slug = createFilePath({ node, getNode, basePath: `pages` })
    console.log(slug)
    /* 
        Checks if 8 numbers are present at start of slug string,
        with the isNaN numerical check recommended here https://stackoverflow.com/a/175787/9761761
        If yes, these numbers and the following hyphen are removed
    */
    if (!isNaN(slug.substring(1, 9))) {
        slug = slug.replace(slug.substring(1, 10), "");
        console.log("removed date. new slug: " + slug);
    }
    createNodeField({
      node,
      name: `slug`,
      value: slug,
    })
  }
}

exports.createPages = async ({ graphql, actions }) => {
  // **Note:** The graphql function call returns a Promise
  // see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise for more info
  const { createPage } = actions

  const result = await graphql(`
    query {
      allMarkdownRemark {
        edges {
          node {
            fields {
              slug
            }
          }
        }
      }
    }
  `)
  result.data.allMarkdownRemark.edges.forEach(({ node }) => {
    createPage({
      path: node.fields.slug,
      component: path.resolve(`./src/templates/blog-post.js`),
      context: {
        // Data passed to context is available
        // in page queries as GraphQL variables.
        slug: node.fields.slug,
      },
    })
  })
}

已知问题:在日期之后共享相同名称的两个页面将相互覆盖。如果存在两个文件/20210309-bees-are-dying.mdx/20690420-bees-are-dying.mdx则只有一页带有 slug 的/bees-are-dying/内容为准。


推荐阅读