以编程方式生成没有来自 Graphql 的 slug 的 Gatsby 页面

Programatically generating Gatsby pages without a slug from Graphql

我在 WordPress 中设置了一个名为项目的 ACF 选项页面

在“项目”选项页面中,有一个 ACF 转发器允许用户添加多个项目。

在 Gatsby 中,我使用 Graphql 在两个文件中查询我的项目数据:

很明显,在 ACF 选项页面的这个转发器字段中,Graphql 中没有 slug。相反,我根据每个项目转发器字段中的嵌套标题文本字段生成一个 slug。

我同时使用 replaceAll() 和 toLowerCase() 方法来创建 slug,然后将其作为我的数据的一部分提供。

这是我的自定义挂钩:

export const useProjectsQueryAlt = () => {

  const data = useStaticQuery(graphql`
    query ProjectsQueryAlt {
      wp {
        projects {
          projects {
            allprojects {
              projectContent
              projectTitle
              featuredImage {
                mediaItemUrl
                id
              }
              projectGallery {
                caption
                id
                mediaItemUrl
              }
            }
          }
        }
      }
    }
    `)

    const project = data.wp.projects.projects.allprojects.map(node => {
      const { projectContent, projectTitle, featuredImage, projectGallery } = node;
        
        const title = node.projectTitle;
        const spacesToHyphen = title.replaceAll(' ', '-');
        const slugFromTitle = spacesToHyphen.toLowerCase()

        return {
          projectContent, 
          projectTitle,
          slug: slugFromTitle,
          featuredImage,
        
          projectGallery: projectGallery.map(node => {
            const { caption, id, mediaItemUrl } = node;
            return {
              caption, 
              id, 
              mediaItemUrl
            }
          })

      }
    })

    return { project }
}

这是我的 gatsby-node 文件:

const path = require('path')

exports.createPages = async ({ graphql, actions }) => {

    const { data } = await graphql(`
    query Projects {
        wp {
            projects {
                projects {
                    allprojects {
                        projectTitle
                    }
                }
            }
        }
    }
    `) 

    data.wp.projects.projects.allprojects.forEach(node => {

        const title = node.projectTitle;

        const spacesToHyphen = title.replaceAll(' ', '-');
        const slugFromTitle = spacesToHyphen.toLowerCase()

        actions.createPage({
            path: '/projects/' + slugFromTitle,
            component: path.resolve('./src/templates/project-details.js'),
            context: { slug: slugFromTitle },
        })
    })

}

这是我的模板文件 project-details.js

import React from 'react'

function ProjectDetails() {

  return (
    <div>
      ...my page template content
    </div>
  )
}

export default ProjectDetails

我现在需要找到一种方法来检查我的“project-details.js”模板文件中的两个附加 slug 是否匹配,以便将相关项目数据显示到相应的 URL。

鉴于我已经在前端生成了 slug,遵循 Gatsby 文档设置动态生成页面与我的用例不一致。我希望有人对这个用例有经验,可以为我指明正确的方向。

您的方法中的问题是您正在根据项目的 title 生成一个“假的”slug,因此您不能使用该字段来过滤任何 GraphQL 节点,因为该字段不存在在项目领域。您最好的选择是使用 title 本身或使用任何自动生成的标识符(id,如果它作为字段存在)。

actions.createPage({
    path: '/projects/' + slugFromTitle,
    component: path.resolve('./src/templates/project-details.js'),
    context: { title },
})

注:可以省略{ title: title }

您仍然可以使用生成的 slug 的 path,这是一种有效的方法。

我假设如果 title 是一个唯一字段,那么 slug 也必须是唯一字段,因此您将是一个有效的过滤器。

现在在 project-details.js:

import React from 'react'

function ProjectDetails({ data }) {
  console.log("my data is", data);

  return (
    <div>
      ...my page template content
    </div>
  )
}

export const query = graphql`
  query($title: String!) {
    yourACFNode(title: { eq: $title} ) {
      # your fields
    }
  }
`

export default ProjectDetails

当然,调整上面的查询以匹配您的 ACF 节点,但得到方法。