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

时间:2019-02-11 19:09:31

标签: gatsby

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

  
      
  1. stories-template.js
  2.   
  3. products.template.js
  4.   

我的故事正在运行故事模板,但是我不确定如何调整和更改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
        }
    }
}
`

这可行,但是现在我想在products-template.js中为产品创建一个不同的模板。现在,我的产品模板基本上是从我的故事模板中复制并粘贴的。

我一生中似乎无法弄清这一点。

2 个答案:

答案 0 :(得分:2)

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

Gatsby不会自动读取模板目录或类似目录中的模板,您需要自己添加逻辑。

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

const postTemplate = path.resolve('src/components/stories-template.js');
const productsTemplate = path.resolve('src/components/products-template.js');

然后,您需要在此处决定何时使用productsTemplate而不是postTemplate

createPage({
  path: node.frontmatter.path,
  component: postTemplate,
})

例如,也许在每个Markdown文件中,您都有template YAML主题:

createPage({
  path: node.frontmatter.path,
  component: node.frontmatter.template === 'product' ? productTemplate : postTemplate,
  })

这是我在自己的网站上尝试以更通用的方式进行处理的方法。网址结构决定了模板:如果位于/journal,它将获取日记模板组件。如果位于/shop,它将获得Shop模板组件。

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

const path = require('path')

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

  // I created an object to hold multiple templates.
  // In this case, my blog posts are at /journal and my
  // products are at /shop, so those are the keys I used here.
  // You might have a different system for determining what files
  // should use what template.
  const templates = {
    journal: path.resolve('src/templates/stories-template.js'),
    shop: path.resolve('src/templates/products-template.js'),
  }

  // Query for all Markdown “nodes”
  // Note I’m using a different GraphQL query, so you’ll need to replace this
  // with yours, or see if something with only the minimum requirements like
  // this works for you.
  return graphql(`
    {
      allMarkdownRemark {
        edges {
          node {
            fields {
              slug
            }
          }
        }
      }
    }
  `).then(result => {
    if (result.errors) {
      console.log(result.errors)
      reject(result.errors)
    }

    // Create pages from Markdown files
    result.data.allMarkdownRemark.edges.forEach(edge => {
      let slug = edge.node.fields.slug

      // Get the part of the slug we want, ex. journal
      let slugKey = slug.split('/')[1]

      // If the slug matches a template, use that, otherwise
      // fallback to the default journal template.
      // You could use your own logic here.
      let template = templates[slugKey] || templates['journal']

      createPage({
        path: slug, // required
        component: template,
        context: { slug: slug },
      })
    })
  })
}

我敢肯定,使用诺言的方式会有所改善,但否则对我来说效果很好,并为您提供了一种添加更多模板的不错方法。

答案 1 :(得分:0)

@kennethormandy的答案是正确的,它将帮助您添加新的博客模板!

我只想向其中添加一点:如果您已经将每个模板的markdown内容组织到了不同的目录中,那么在每个内容的最前面添加一个template道具将是多余的。 / p>

每个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
  })
}