如何为我的 Gatsby 网站创建第二个博客模板
Posted
技术标签:
【中文标题】如何为我的 Gatsby 网站创建第二个博客模板【英文标题】:How to create a second blog template to my Gatsby Site 【发布时间】:2019-07-05 08:31:19 【问题描述】:我的 Gatsby 网站需要 2 个博客模板:
故事模板.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
`
这可行,但现在我想在 products-template.js 中为产品创建不同的模板。现在我的产品模板基本上只是从我的故事模板中复制和粘贴的。
我这辈子都想不通。
【问题讨论】:
欢迎来到 SO!这涉及几个步骤(创建新模板、设置新内容、进行新查询、创建新页面),您在哪些步骤遇到问题?您尝试了什么,遇到了什么错误? 【参考方案1】:就像提到的第一条评论一样,这里可能需要更多的上下文,但我会试一试。我认为问题在于无论页面如何,您都在告诉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 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 的方式,但除此之外这对我来说效果很好,并为您提供了一种添加更多模板的好方法。
【讨论】:
【参考方案2】:@kennethormandy 的回答是正确的,将帮助您添加新的博客模板!
我只是想补充一点:如果您已经将每个模板的 markdown 内容组织到不同的目录中,那么在每个内容的 frontmatter 中添加一个 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
)
【讨论】:
以上是关于如何为我的 Gatsby 网站创建第二个博客模板的主要内容,如果未能解决你的问题,请参考以下文章
正确地将第二个动态模板添加到 Gatsby/NetlifyCMS - 我哪里出错了?