盖茨比创建页面

Posted

技术标签:

【中文标题】盖茨比创建页面【英文标题】:Gatsby Create Pages 【发布时间】:2021-01-21 21:49:49 【问题描述】:

我正在尝试创建一个 gatsby 网站,我在其中发布了项目,每个项目都有标签。我遵循了有关创建 gatsby 博客的基本教程,现在正在研究 gatsby 的标签,如其网站上记录的那样。在将变量名从路径更改为 slug 以避免保留字的过程中,我似乎搞砸了,因为我不能再创建博客文章页面,也不能标记页面。每篇文章都包含在一个以文章标题命名的文件夹中,其中包含一个 index.md 文件,用于定义其内容、日期、标签等。

当我尝试运行 gatsby develop 时输出以下错误,

错误 #11323

Your site's "gatsby-node.js" must set the page path when creating a page.

The page object passed to createPage:

    "slug": "/an-example-post",
    "component": "C:\\Users\\Monolith\\Documents\\programming\\webdev\\Gatsby-Portfolio\\src\\templates\\post.js",
    "context": 
        "slug": "/an-example-post"
    

我的 gatsby-node.js

const path = require('path');

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

     const postTemplate = path.resolve('src/templates/post.js');
     const tagTemplate = path.resolve("src/templates/tags.js")
     //const postTemplate = require.resolve('src/templates/post.js');
     //const tagTemplate = require.resolve("src/templates/tags.js")
     
     return graphql(`
        allMarkdownRemark
            edges
                node 
                    html
                    id
                    frontmatter
                        slug
                        title
                    
                
            
        
    
        tagsGroup: allMarkdownRemark(limit: 2000) 
            group(field: frontmatter___tags) 
              fieldValue
            
          

    `)
    .then(res => 
        if(res.errors)
            return Promise.reject(res.errors);
        


        
        res.data.allMarkdownRemark.edges.forEach( (node) => 
            createPage(
                slug: node.frontmatter.slug,
                component: postTemplate,
                context: 
                    slug:node.frontmatter.slug
                ,
            )
        )

          // Extract tag data from query
        const tags = res.data.tagsGroup.group

        // Make tag pages
        tags.forEach(tag => 
            createPage(
                // path: `/tags/$_.kebabCase(tag.fieldValue)/`,
                slug: `/tags/$(tag.fieldValue)/`,
                component: tagTemplate,
                context: 
                    tag: tag.fieldValue,
                ,
            )
        )

    ) 

如前所述,我担心作为保留字的路径变量可能是一个问题,但我进一步使用它而不是省略它,所以现在它一直保留。

示例 post.js

import React from 'react';
import  graphql  from 'gatsby';
import Layout from "../components/layout"

export default function Template(data) 
    const markdownRemark: post = data;

    return(
        <Layout>
        <div>
            <h1 className="postTitle">post.frontmatter.title</h1>
            <div className="tagGroup">
                post.frontmatter.tags.map((tag, index) => (
                    <div key=index>
                        <h2 className = "tagStyle">tag</h2>
                    </div>
                ))
            </div>
            <p>post.frontmatter.description</p>
            <p>post.frontmatter.date</p>            
            /* <h2 className="tagStyle">post.frontmatter.tags + " "</h2> */
            <div dangerouslySetInnerHTML=__html: post.html />
        </div>
        </Layout>
    )



export const postQuery = graphql`
    #query BlogPostByPath($slug: String!) 
    query($slug: String!) 
        markdownRemark(frontmatter:  slug: eq: $slug ) 
            html
            frontmatter 
                slug
                title
                description
                date
                tags
            
        
    
`

tags.js 与 gatsby 的默认值非常相似,只是对内容稍作改动。这是我正在使用的 Graphql 查询。

Tags.propTypes = 
  pageContext: PropTypes.shape(
    tag: PropTypes.string.isRequired,
  ),
  data: PropTypes.shape(
    allMarkdownRemark: PropTypes.shape(
      totalCount: PropTypes.number.isRequired,
      edges: PropTypes.arrayOf(
        PropTypes.shape(
          node: PropTypes.shape(
            frontmatter: PropTypes.shape(
              title: PropTypes.string.isRequired,
           //   slug: PropTypes.string.isRequired,
            ),
            fields: PropTypes.shape(
              slug: PropTypes.string.isRequired,
            ),
          ),
        ).isRequired
      ),
    ),
  ),


export default Tags

export const pageQuery = graphql`
  query($tag: String) 
    allMarkdownRemark(
      limit: 2000
      sort:  fields: [frontmatter___date], order: DESC 
      filter:  frontmatter:  tags:  in: [$tag]   
    ) 
      totalCount
      edges 
        node 
           fields 
             slug
           
          frontmatter 
            title
          
        
      
    
  
`

如果有人有任何信息可以帮助我指明正确的方向,我将不胜感激。我已经浏览了几个小时的 gatsby 文档,但还没有取得实质性进展。

【问题讨论】:

" createPage( // 此页面的路径 - 必填路径:" - 不使用 'path' 变量并不意味着它不能用作道具名称 嗯好的,所以我将请求更改为 createPage( path: node.frontmatter.slug, component: postTemplate, context: slug:node.frontmatter.slug。但错误消息现在显示上下文中的路径和 slug 为空。我不确定我理解你的意思。 【参考方案1】:

您在上下文中传递了tag,但期待slug

    createPage(
        slug: `/tags/$(tag.fieldValue)/`,
        component: tagTemplate,
        context: 
            tag: tag.fieldValue,
        ,
    )

还有:

   query($slug: String!) 

上下文是一种将数据传递给组件模板以使用它来过滤数据的方法。理想情况下应该是一个唯一的参数(如slugid 等)。这样,在您的 gatsby-node.js 中,您应该获取所有帖子,按上下文传递一个唯一字段,并在模板中使用该变量来获取每个帖子所需的所有数据。

此外,您必须为您的函数提供path,而不是slug

您应该将createPage 函数更改为:

    createPage(
        path: `/tags/$tag.fieldValue/`,
        component: tagTemplate,
        context: 
            slug: tag.fieldValue,
        ,
    )

请记住,fieldValue 应该是一个 slug(或某种),尽管有不同的命名。

我会推荐阅读 Gatsby 的教程:https://www.gatsbyjs.com/tutorial/part-seven/

【讨论】:

太棒了!非常感谢您的详尽回答。我似乎通过这些更改做了一些事情,并认为这绝对是问题的解决方案。我还为我的 tags.js 发布了错误的最终代码 sn-p。我相信这应该是用于生成标签的查询,但它无法查询 MarkdownRemark 的字段字段,尽管 allMarkdownRemark 似乎是 gatsbyjs 教程中建议的主要方法。

以上是关于盖茨比创建页面的主要内容,如果未能解决你的问题,请参考以下文章

盖茨比 - 下载的文件总是损坏

javascript 盖茨比:单独的帖子和页面

如何显示特定页面组的特定标题。盖茨比

盖茨比没有找到graphql片段

盖茨比:上下文更新导致无限渲染循环

可选字段图像和 'childImageSharp' 为 null |盖茨比、GraphQL 和 YAML