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

  • 本文关键字:第二个 创建 网站 gatsby
  • 更新时间 :
  • 英文 :


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

  1. 存储模板.js
  2. 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
}
}
}
`

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

我似乎一辈子都搞不明白这一点。

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

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

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

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文件中,都有templateYAML frontmatter:

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

以下是我如何在自己的网站上尝试以一种稍微更通用的方式来处理它。URL结构决定了模板:如果它位于/journal,它将获得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 },
})
})
})
}

我相信我使用promise的方式可以改进,但除此之外,这对我来说很好,并为您提供了一种添加更多模板的好方法。

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

我只想补充一点:如果你已经将每个模板的markdown内容组织到不同的目录中,那么在每个内容的前面添加一个template道具会让人觉得多余。

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

相关内容

最新更新