Gatsby 如何为我的盖茨比网站创建第二个博客模板

Gatsby 如何为我的盖茨比网站创建第二个博客模板,gatsby,Gatsby,我的盖茨比网站需要2个博客模板: stories-template.js products.template.js 我已经为我的故事运行了故事模板,但我不确定如何调整和更改gatsby node+products.template.js中的现有代码,以便为我的产品创建第二个(不同的)模板 我尝试了所有的解决方案和过去的问题,但没有运气 我在gatsby-node.js中的代码: const path = require('path'); exports.createPages = ({acti

我的盖茨比网站需要2个博客模板:

  • stories-template.js
  • products.template.js
  • 我已经为我的故事运行了故事模板,但我不确定如何调整和更改gatsby node+products.template.js中的现有代码,以便为我的产品创建第二个(不同的)模板

    我尝试了所有的解决方案和过去的问题,但没有运气

    我在gatsby-node.js中的代码:

    const path = require('path');
    
    exports.createPages = ({actions, graphql}) => {
    const { createPage } = actions
    
    const postTemplate = path.resolve('src/components/stories-template.js');
    
    return graphql(`
    {
        allMarkdownRemark {
            edges {
              node {
                html  
                id 
                frontmatter {
                  path
                  title
                  author
                  date
                }
              }
            }
          }
    }
    `).then(res => {
        if(res.errors) {
            return Promise.reject(res.errors)
        }
    
        res.data.allMarkdownRemark.edges.forEach(({ node }) => {
                createPage({
                    path: node.frontmatter.path,
                    component: postTemplate,
            })
        })
    })
    }
    
    stories-template.js中的我的代码:

    import React from 'react'
    import Layout from '../components/layout'
    
    
    export default function Template({data}) {
    const post = data.markdownRemark
    
    return(<Layout>
        <div>
            <p>Stories</p>
            <br />
            <p>{post.frontmatter.title}</p>
    
            <div dangerouslySetInnerHTML={{__html: post.html}} />
        </div>
        </Layout>
    )
    }
    
    
    export const postQuery = graphql`
    query BlogPostByPath($path: String!) {
        markdownRemark(frontmatter: { path: {eq:$path}}){
            html
            frontmatter{
                path
                title
                date
                author
            }
        }
    }
    `
    
    从“React”导入React
    从“../components/Layout”导入布局
    导出默认函数模板({data}){
    const post=data.markdown备注
    返回(
    故事


    {post.frontmatter.title}

    ) } export const postQuery=graphql` 查询BlogPostByPath($path:String!){ markdownRemark(FrontMate:{path:{eq:$path}}){ html 前沿物质{ 路径 标题 日期 作者 } } } `
    这是可行的,但现在我想在products-template.js中为产品创建一个不同的模板。现在,我的产品模板基本上只是从我的故事模板复制和粘贴


    就我个人而言,我似乎无法理解这一点。

    就像前面提到的第一条评论一样,这里可能需要更多的上下文,但我会尝试一下。我认为问题在于,不管页面是什么,您都在告诉
    createPage
    函数使用
    postmlate
    模板组件

    盖茨比不会自动读取模板目录中的模板或类似的内容,您需要自己添加逻辑

    首先,您需要使用其他模板,例如:

    exports.createPages = async ({ actions, graphql }) => {
      const { createPage } = actions
      const results = await graphql(`
        {
           allMarkdownRemark {
             edges {
               node {
                 fileAbsolutePath
               }
               // ...other useful fields
             }
           }
        }
      `)
    
      if (results.errors) throw results.errors
      results.data.allMarkdownRemark.edges.forEach(({ node }) => {
        let template
        if (node.fileAbsolutePath.includes('/blogs/')) template = path.resolve('path/to/blog/template')
    
        createPage({ ... }) // ...etc
      })
    }
    
    constPostTemplate=path.resolve('src/components/stories template.js');
    const productsTemplate=path.resolve('src/components/products template.js');
    
    然后,您需要在此处决定何时使用
    productsTemplate
    而不是
    postTemplate

    createPage({
    路径:node.frontmatter.path,
    组件:postTemplate,
    })
    
    例如,可能在每个降价文件中,都有
    template
    YAML frontmatter:

    createPage({
    路径:node.frontmatter.path,
    组件:node.frontmatter.template==“产品”?产品模板:postTemplate,
    })
    
    以下是我如何在自己的网站上尝试并以一种更为通用的方式处理它。URL结构决定了模板:如果它位于
    /journal
    ,它将获得日志模板组件。如果它位于
    /shop
    ,它将获取shop模板组件

    这可能不足以进入您现有的站点,但希望它能让您更接近:

    const path=require('path'))
    exports.createPages=({graphql,actions})=>{
    const{createPage}=actions
    //我创建了一个对象来保存多个模板。
    //在本例中,我的博客帖子位于/journal,我的
    //产品在/商店,所以这些是我在这里使用的钥匙。
    //您可能有不同的系统来确定哪些文件
    //应该使用什么样的模板。
    常量模板={
    日志:path.resolve('src/templates/stories template.js'),
    shop:path.resolve('src/templates/products template.js'),
    }
    //查询所有标记“节点”
    //注意,我使用的是另一个GraphQL查询,因此您需要替换它
    //用你的,或者看看只有最低要求的东西
    //这对你有用。
    返回图(`
    {
    所有的标记{
    边缘{
    节点{
    田地{
    鼻涕虫
    }
    }
    }
    }
    }
    `)。然后(结果=>{
    if(result.errors){
    console.log(result.errors)
    拒绝(结果错误)
    }
    //从标记文件创建页面
    result.data.allMarkdownRemark.edges.forEach(edge=>{
    设slug=edge.node.fields.slug
    //得到我们想要的弹头,前杂志
    让slugKey=slug.split('/')[1]
    //如果slug与模板匹配,则使用该模板,否则
    //回退到默认日志模板。
    //你可以用你自己的逻辑。
    让模板=模板[slugKey]| |模板['journal']
    创建页面({
    路径:slug,//必需
    组件:模板,
    上下文:{slug:slug},
    })
    })
    })
    }
    

    我相信我使用承诺的方式会有所改进,但除此之外,这对我来说效果很好,并为您提供了添加更多模板的体面方式。

    @Kennethermandy的回答是正确的,将帮助您添加新的博客模板

    我只想补充一点:如果您已经将每个模板的降价内容组织到了不同的目录中,那么在每个内容的前端添加
    模板
    道具就显得多余了

    每个MarkdownRemark节点都有一个
    fileAbsolutePath
    字段,允许您根据内容的来源进行过滤

    例如:

    exports.createPages = async ({ actions, graphql }) => {
      const { createPage } = actions
      const results = await graphql(`
        {
           allMarkdownRemark {
             edges {
               node {
                 fileAbsolutePath
               }
               // ...other useful fields
             }
           }
        }
      `)
    
      if (results.errors) throw results.errors
      results.data.allMarkdownRemark.edges.forEach(({ node }) => {
        let template
        if (node.fileAbsolutePath.includes('/blogs/')) template = path.resolve('path/to/blog/template')
    
        createPage({ ... }) // ...etc
      })
    }
    

    欢迎来到SO!这涉及几个步骤(创建新模板、设置新内容、进行新查询、创建新页面),您在哪些步骤遇到问题?你试过什么,犯了什么错误?