Gatsby `createPage` 正在生成具有相同数据的页面

Posted

技术标签:

【中文标题】Gatsby `createPage` 正在生成具有相同数据的页面【英文标题】:Gatsby `createPage` is generating pages with the same data 【发布时间】:2020-01-05 20:13:18 【问题描述】:

gatsby-config.js 配置为从./content 目录获取所有降价文件。

ServicePostBlogPost 模板从 ./src/content/services./src/content/blog 目录。

gatsby-node.js 根据templateKey 中设置的./src/content/ 对数据进行排序 markdown 文件的 frontmatter 并将其传递给生成页面的createPage/services/service-name/blog/blog-article-name URL 上。

我遇到的问题是所有/services/service-name/blog/blog-article-name 页面 使用来自./services/./blog/ 目录的第一篇文章的数据生成。

Link on the repo Link on the website

gatsby-config.js

const proxy = require('http-proxy-middleware')

module.exports = 
  siteMetadata: 
    title: 'Gatsby + Netlify CMS Starter',
    description:
      'This repo contains an example business website that is built with Gatsby, and Netlify CMS.It follows the JAMstack architecture by using Git as a single source of truth, and Netlify for continuous deployment, and CDN distribution.',
  ,
  plugins: [
    'gatsby-plugin-react-helmet',
    'gatsby-plugin-sass',
    
      // keep as first gatsby-source-filesystem plugin for gatsby image support
      resolve: 'gatsby-source-filesystem',
      options: 
        path: `$__dirname/static/img`,
        name: 'uploads',
      ,
    ,
    
      resolve: 'gatsby-source-filesystem',
      options: 
        path: `$__dirname/src/content`,
        name: 'content',
      ,
    ,
    
      resolve: 'gatsby-source-filesystem',
      options: 
        path: `$__dirname/src/img`,
        name: 'images',
      ,
    ,
    'gatsby-plugin-sharp',
    'gatsby-transformer-sharp',
    
      resolve: 'gatsby-transformer-remark',
      options: 
        plugins: [
          
            resolve: 'gatsby-remark-relative-images',
            options: 
              name: 'uploads',
            ,
          ,
          
            resolve: 'gatsby-remark-images',
            options: 
              // It's important to specify the maxWidth (in pixels) of
              // the content container as this plugin uses this as the
              // base for generating different widths of each image.
              maxWidth: 2048,
            ,
          ,
          
            resolve: 'gatsby-remark-copy-linked-files',
            options: 
              destinationDir: 'static',
            ,
          ,
        ],
      ,
    ,
    
      resolve: 'gatsby-plugin-netlify-cms',
      options: 
        modulePath: `$__dirname/src/cms/cms.js`,
      ,
    ,
    
      resolve: 'gatsby-plugin-purgecss', // purges all unused/unreferenced css rules
      options: 
        develop: true, // Activates purging in npm run develop
        purgeOnly: ['/all.sass'], // applies purging only on the bulma css file
      ,
    , // must be after other CSS plugins
    'gatsby-plugin-netlify', // make sure to keep it last in the array
  ],
  // for avoiding CORS while developing Netlify Functions locally
  // read more: https://www.gatsbyjs.org/docs/api-proxy/#advanced-proxying
  developMiddleware: app => 
    app.use(
      '/.netlify/functions/',
      proxy(
        target: 'http://localhost:9000',
        pathRewrite: 
          '/.netlify/functions/': '',
        ,
      )
    )
  

gatsby-node.js

const _ = require('lodash')
const path = require('path')
const  createFilePath  = require('gatsby-source-filesystem')
const  fmImagesToRelative  = require('gatsby-remark-relative-images')

exports.createPages = async ( actions, graphql ) => 
  const  createPage  = actions

  const blogs = await graphql(`
    
      blogs: allMarkdownRemark(
        limit: 1000
        filter:  frontmatter:  templateKey:  eq: "blog-post"   
        sort: 
          fields: [frontmatter___date]
          order: [DESC]
        
      ) 
        edges 
          node 
            id
            fields 
              slug
            
            html
            frontmatter 
              title
              templateKey
              date
            
          
        
      
    
  `)

  const BlogPostTemplate = path.resolve(`src/templates/BlogPost.js`)
  blogs.data.blogs.edges.forEach(( node ) => 

    createPage(
      path: node.fields.slug,
      component: BlogPostTemplate,
      context: ,
    );
  );

  const services = await graphql(`
    
      services: allMarkdownRemark(
        limit: 1000
        filter:  frontmatter:  templateKey:  eq: "service-post"   
      ) 
        edges 
          node 
            id
            fields 
              slug
            
            html
            frontmatter 
              title
              templateKey
            
          
        
      
    
  `)

  const ServicePostTemplate = path.resolve(`src/templates/ServicePost.js`)
  services.data.services.edges.forEach(( node ) => 
    createPage(
      path: node.fields.slug,
      component: ServicePostTemplate,
    );
  );


exports.onCreateNode = ( node, actions, getNode ) => 
  const  createNodeField  = actions
  fmImagesToRelative(node) // convert image paths for gatsby images

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

./src/templates/BlogPost.js

import React from 'react'
import PropTypes from 'prop-types'
import Helmet from 'react-helmet'
import  graphql  from 'gatsby'
import Layout from '../components/Layout'
import Content,  HTMLContent  from '../components/Content'

export const BlogPostTemplate = (
  content,
  contentComponent,
  description,
  title,
  helmet,
) => 
  const PostContent = contentComponent || Content

  return (
    <section>
      helmet || ''
        <h1>
          title
        </h1>

        Blog post template

        <p>description</p>
        <PostContent content=content />
    </section>
  )


BlogPostTemplate.propTypes = 
  content: PropTypes.node.isRequired,
  contentComponent: PropTypes.func,
  title: PropTypes.string,
  helmet: PropTypes.object,


const BlogPost = ( data ) => 
  // console.log('Blog Post Data', JSON.stringify(data))

  const  markdownRemark: post  = data

  return (
    <Layout>
      <BlogPostTemplate
        content=post.html
        contentComponent=HTMLContent
        helmet=
          <Helmet titleTemplate="%s | Blog">
            <title>`$post.frontmatter.title`</title>
          </Helmet>
        
        title=post.frontmatter.title
      />
    </Layout>
  )


BlogPost.propTypes = 
  data: PropTypes.shape(
    markdownRemark: PropTypes.object,
  ),


export default BlogPost

export const pageQuery = graphql`
  query BlogPostByID 
    markdownRemark(frontmatter:  templateKey:  eq: "blog-post"  ) 
      id
      html
      frontmatter 
        date(formatString: "MMMM DD, YYYY")
        title
      
    
  
`

./src/content/blog/blog-post-1.md

---
templateKey: blog-post
title: Blog post 1 title
date: 2014-12-17T15:04:10.000Z
---

Blog post 1 body

【问题讨论】:

解决于:github.com/gatsbyjs/gatsby/issues/17331#issuecomment-527286245 【参考方案1】:

你解决了吗?

您是否尝试在创建页面时将节点放入上下文中

gatsby-node.js

    createPage(
          path: node.fields.slug,
          component: BlogPostTemplate,
          context: node, // adding node in here and then pulling it as a 
                               // props everytime you create a page?
        );

./src/templates/BlogPost.js

    export const BlogPostTemplate = (node) => 

 <h1>node.context.node.frontmatter.title<h1> // sorry don't know what the extact api route would be but i think tis something like this. just double check with a console.log



其余的可能会在创建页面之前扩展查询以获取所有数据字段。

我不知道这是否适合你,但我认为可能值得一提。

【讨论】:

以上是关于Gatsby `createPage` 正在生成具有相同数据的页面的主要内容,如果未能解决你的问题,请参考以下文章

javascript Gatsby / Contentful - createPages

如何将特定上下文注入 Gatsby 中的所有页面?

如何在Gatsby中反转页面顺序?

盖茨比类别 slugs 在动态类别页面中不起作用

Gatsby slug 没有生成正确的页面

在Gatsby JS中动态生成路由