我对 Gatsby 还很陌生,希望拥有多个可用于不同页面的模板,例如 Landingpage、Contact 和 About 不能使用相同的模板。
我现在在 gatsby-node.js 中编写了一个丑陋的代码,但它只适用于两个模板,这是我的代码(顺便说一句,我从 markdownfiles 中获取数据):
Mardown 文件 1:
---
title: 'Index page'
slug: '/'
template: indexTemplate //This is where i declare which template it shall use
content: 'Index content'
---
Mardown 文件 2:
---
slug: '/my-first-post'
date: '2019-05-04'
title: 'My first blog post!'
content: 'Content post 1'
template: postTemplate
---
gatsby-node.js:
exports.createPages = async ({ actions, graphql, reporter }) => {
const { createPage } = actions
const result = await graphql(`
query{
allMarkdownRemark {
nodes {
frontmatter {
slug
template
}
}
}
}
`)
const postTemplate = require.resolve(`./src/templates/postTemplate.js`)
const indexTemplate = require.resolve(`./src/templates/indexTemplate.js`)
const aboutTemplate = require.resolve(`./src/templates/aboutTemplate.js`) // I also want a template for my aboutpage
// Handle errors
if (result.errors) {
reporter.panicOnBuild(`Error while running GraphQL query.`)
return
}
result.data.allMarkdownRemark.nodes.forEach( post => {
createPage({
path: post.frontmatter.slug,
component: post.frontmatter.template === 'indexTemplate' ? indexTemplate : postTemplate, // Here is where the ugly "magic" happens...
context: {
slug: post.frontmatter.slug,
},
})
})
}
最佳答案
使用 gatsby-node.js 的想法是使用 createPage
API 从某些数据源(CMS、Markdown 文件、JSON 文件、外部 API 等)创建动态页面。 。换句话说,创建具有来自数据源的未知 slug 或名称的动态页面确实很有用。这个想法是查询所有类型的数据(例如帖子)并通过上下文传递一些唯一信息(通常是 slug
或 id
)作为过滤器参数来执行另一个操作在模板中查询。
就您而言,这适合您的博客(markdown 文件 2),但不适用于其他已知页面,例如索引、关于等(markdown 文件 1)。它们是已定义的已知页面,应使用 page query 进行区别对待。 。它们不是模板,因为它们是独特的页面,您不会有两个可以重用主页模板的不同主页。
例如,要识别帖子和主页之间的不同 Markdown 页面,您可以使用 key
值来过滤查询。
---
title: 'Index page'
slug: '/'
key: 'home'
template: indexTemplate //This is where i declare which component it shall use
content: 'Index content'
---
Content of the index page.
还有:
---
slug: '/my-first-post'
date: '2019-05-04'
key: 'post'
title: 'My first blog post!'
content: 'Content post 1'
template: postTemplate
---
动态创建页面时(通过 gatsby-node.js
),方法应如下所示:
const path = require(`path`)
const { createFilePath } = require(`gatsby-source-filesystem`)
exports.onCreateNode = ({ node, getNode, actions }) => {
const { createNodeField } = actions
if (node.internal.type === `MarkdownRemark`) {
const slug = createFilePath({ node, getNode, basePath: `pages` })
createNodeField({
node,
name: `slug`,
value: slug,
})
}
}
exports.createPages = async ({ graphql, actions }) => {
const { createPage } = actions
const result = await graphql(`
query {
allMarkdownRemark(
filter: { frontmatter: { key: { eq: "article" }}}) {
edges {
node {
fields {
slug
}
}
}
}
}
`)
result.data.allMarkdownRemark.edges.forEach(({ node }) => {
createPage({
path: node.fields.slug,
component: path.resolve(`./src/templates/blog-post.js`),
context: {
// Data passed to context is available
// in page queries as GraphQL variables.
slug: node.fields.slug,
},
})
})
}
注意key
值的过滤器。
然后,在您的博客文章
(模板)中:
import React from "react"
import { graphql } from "gatsby"
import Layout from "../components/layout"
export default function BlogPost({ data }) {
const post = data.markdownRemark
return (
<Layout>
<div>
<h1>{post.frontmatter.title}</h1>
<div dangerouslySetInnerHTML={{ __html: post.html }} />
</div>
</Layout>
)
}
export const query = graphql`
query($slug: String!) {
markdownRemark(fields: { slug: { eq: $slug } }) {
html
frontmatter {
title
}
}
}
`
对于您的静态页面,只需在页面上进行查询即可。对于您的 index.js
:
import React from 'react'
import { graphql } from 'gatsby'
const HomePage = ({data}) => {
return (
<div>
Your page title is {data.nodes[0].frontmatter.title}
</div>
)
}
export const query = graphql`
query HomePageQuery {
allMarkdownRemark(filter: { frontmatter: { key: { eq: "home" }}}) {
nodes{
frontmatter{
title
}
}
}
}
`
export default HomePage
请随意调整代码以满足您的需求。重要的是,您应该区分应用作模板的内容(博客、帖子、文章或其他动态数据)和应静态处理的内容(主页、关于或其他静态页面)。
当然,根据问题的范围,您可以有多个模板,一个用于帖子,另一个用于评论(或其他动态数据)。您可以简单地通过将查询结果保存在变量中并调用两次 createPage
API 来实现它:
const result1 = await graphql(`
query{
allMarkdownRemark {
nodes {
frontmatter {
slug
template
}
}
}
}
`)
const result2 = await graphql(`
query{
allMarkdownRemark {
nodes {
frontmatter {
slug
template
}
}
}
}
`)
const postTemplate = require.resolve(`./src/templates/postTemplate.js`)
const reviewsTemplate = require.resolve(`./src/templates/reviewsTemplate.js`)
// Handle errors
if (result1.errors || result2.errors) {
reporter.panicOnBuild(`Error while running GraphQL query.`)
return
}
result1.data.allMarkdownRemark.nodes.forEach( post => {
createPage({
path: post.frontmatter.slug,
component: postTemplate
context: {
slug: post.frontmatter.slug,
},
})
})
result2.data.allMarkdownRemark.nodes.forEach( review => {
createPage({
path: review.frontmatter.slug,
component: reviewsTemplate
context: {
slug: review.frontmatter.slug,
},
})
})
关于reactjs - Gatsby.js 中的多个模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64677182/