【问题标题】:Stop Gatsby blog post slug from including individual post folders阻止 Gatsby 博客帖子 slug 包含单个帖子文件夹
【发布时间】:2020-07-16 02:56:43
【问题描述】:

我在创建个人 Gatsby 网站时遇到了一个问题,即博客文章文件在 slug 中包含其独特的文件夹。

例如一个文件结构:

data
|
|– blog
   |
   |– blog-1
   |  |
   |  |-blog-1.mdx
   |  |-img.jpg
   |
   |– blog-2
   |  |
   |  |-blog-2.mdx
   |  |-img.jpg
   |
   |– blog-3
   |  |
   |  |-blog-3.mdx
   |  |-img.jpg

例如,会产生这样的蛞蝓

{
  "data": {
    "allMdx": {
      "edges": [
        {
          "node": {
            "fields": {
              "slug": "/blog-1/blog-1/"
            },
            "frontmatter": {
              "title": "Blog 1",
              "posttype": "blog"
            }
          }
        },
        {
          "node": {
            "fields": {
              "slug": "/blog-2/blog-2/"
            },
            "frontmatter": {
              "title": "Blog 2",
              "posttype": "blog"
            }
          }
        },
        {
          "node": {
            "fields": {
              "slug": "/blog-3/blog-3/"
            },
            "frontmatter": {
              "title": "Blog 3",
              "posttype": "blog"
            }
          }
        },

我希望他们会产生这样的蛞蝓:

        {
          "node": {
            "fields": {
              "slug": "/blog-1/"
            },
            "frontmatter": {
              "title": "Blog 1",
              "posttype": "blog"
            }
          }
        },

blog 文件夹的路径包含在我的 gatsby-config 中,如下所示:

    {
      resolve: `gatsby-source-filesystem`,
      options: {
        path: `${__dirname}/data/blog`,
        name: `blog`,
      },
    },

然后我的 gatsby-node 文件夹是这样设置的:

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

exports.createPages = ({ graphql, actions }) => {
  const { createPage } = actions
  const blogPost = path.resolve(`./src/templates/blog-post.js`)
  const portfolioPost = path.resolve(`./src/templates/portfolio-post.js`)
  const journeyPost = path.resolve(`./src/templates/journey-post.js`)

  return graphql(
    `
      {
        allMdx(
          sort: { fields: [frontmatter___date], order: DESC }
          limit: 1000
        ) {
          edges {
            node {
              fields {
                slug
              }
              frontmatter {
                title
                posttype
              }
            }
          }
        }
      }
    `
  ).then(result => {
    if (result.errors) {
      throw result.errors
    }

    const posts = result.data.allMdx.edges

    posts.forEach((post, index) => {
      const previous = index === posts.length - 1 ? null : posts[index + 1].node
      const next = index === 0 ? null : posts[index - 1].node

      if (post.node.frontmatter.posttype == "portfolio") {
        createPage({
          path: `/portfolio${post.node.fields.slug}`,
          component: portfolioPost,
          context: {
            slug: post.node.fields.slug,
            previous,
            next,
          },
        })
      } else if (post.node.frontmatter.posttype == "journey") {
        createPage({
          path: `/journey${post.node.fields.slug}`,
          component: journeyPost,
          context: {
            slug: post.node.fields.slug,
            previous,
            next,
          },
        })
      } else {
        createPage({
          path: `/blog${post.node.fields.slug}`,
          component: blogPost,
          context: {
            slug: post.node.fields.slug,
            previous,
            next,
          },
        })
      }
    })

    return null
  })
}

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

  if (node.internal.type === `Mdx`) {
    const value = createFilePath({ node, getNode })
    createNodeField({
      name: `slug`,
      node,
      value,
    })
  }
}

请注意,此时此文件中的旅程和作品集路径与博客路径完全相同。它们的设置方式完全相同,只是根据posttype 分开。页面创建得很好,但它们都使用了不需要的 folder/file.mdx slug。

【问题讨论】:

    标签: javascript reactjs graphql gatsby


    【解决方案1】:

    我确信有更好的方法,但我能够通过在 gatsby-node.js 中进行更改以仅从文件路径中获取最后一个斜杠 (/) 之后的子字符串来解决它。如果有人知道更好的方法,我会很高兴知道的。

    旧:

    exports.onCreateNode = ({ node, actions, getNode }) => {
      const { createNodeField } = actions
    
      if (node.internal.type === `MarkdownRemark`) {
        const value = createFilePath({ node, getNode })
        createNodeField({
          name: `slug`,
          node,
          value,
        })
      }
    }
    

    新:

    exports.onCreateNode = ({ node, actions, getNode }) => {
      const { createNodeField } = actions
    
      if (node.internal.type === `MarkdownRemark`) {
        const value = createFilePath({ node, getNode, trailingSlash:false })
        createNodeField({
          name: `slug`,
          node,
          value: `${value.indexOf("/") > -1 ? value.substring(value.lastIndexOf("/")) : value}`,
        })
      }
    }
    

    【讨论】:

      【解决方案2】:

      通过查看其他博客示例已修复。

      帖子文件名必须是index.mdindex.mdx

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-03-18
        • 2017-07-01
        • 2021-06-10
        • 1970-01-01
        • 2020-09-04
        • 1970-01-01
        • 1970-01-01
        • 2020-07-24
        相关资源
        最近更新 更多