首页 > 解决方案 > 在 Gatsby 中以编程方式创建帖子时,如何使用多个模板显示来自 Contentful API 的博客帖子

问题描述

我一直在关注Gatsby 网站上的初学者教程,并且对使用多个博客文章模板有疑问。

如果需要为博客使用两个或更多模板,例如:

  1. 一个模板,一个图像和一个富文本块。
  2. 一个包含多个图像和多个富文本块的模板。

当在相同的 URL 结构中以编程方式生成页面时,如何在 Gatsby 中实现这一点,例如:

/blog/post-title-1(使用模板 1) /blog/post-title-2(使用模板 2)

谢谢。

标签: gatsbycontentful

解决方案


当然,这是可行的,但请记住,您需要将该信息(选择的布局)提供给您的代码。如果您使用文件系统路由 API 遵循本教程,则需要切换到创建动态页面的“经典”版本,gatsby-node.js因为需要在某处提供这种逻辑以让 Gatsby 意识到这一点。

您可以只添加一个名为 Contentful 的字段layout,在这种情况下可以是整数或类似的东西,然后在您的gatsby-node.js:

const path = require("path")

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

  const result = await graphql(
    `
          {
            allContentfulBlogPost {
              edges {
                node {
                  layout
                  slug
                }
              }
            }
          }
    `
  )

  if (result.errors) {
    reporter.panicOnBuild(`Error while running GraphQL query.`)
    return
  }


  const blogPostTemplate1 = path.resolve(`src/templates/blog-post-1.js`)
  const blogPostTemplate2 = path.resolve(`src/templates/blog-post-2.js`)

  const posts = result.data.allContentfulBlogPost.edges
  posts.forEach((post, index) => {
    createPage({
      path: `/blog/${post.node.slug}/`,
      component: post.node.layout === "1" ? blogPostTemplate1 : blogPostTemplate2,
      context: {
        slug: post.node.slug
      },
    })
   })
  })
}

文件系统路由 API 使您免于在您的标准方法中添加这种查询 + 逻辑,gatsby-node.js但由于它不支持过滤(还),您需要添加一些逻辑,您需要返回到“标准”的方法。

基本上,您正在获取 Contentful 数据,查询 theslug和 the layout(新字段),并根据该条件创建动态页面。

请注意,在 中component,您正在使用三元条件根据布局字段选择一个或另一个模板。当然,根据需要调整它。理想情况下,在复杂的方法(超过 2 个布局)中,它应该是一个可读性的函数。

您的遗留代码(您的模板查询)的其余部分将单独工作,因为您使用以下上下文提供 slug(如您之前所做的那样):

      context: {
        slug: post.node.slug
      },

推荐阅读