Gatsby程序化生成博客页面时如何通过Contentful API使用多套模板
实现方案
步骤1:Contentful 内容模型配置(可选但更推荐)
- 在你现有的博客内容模型中新增一个模板类型短文本字段,设置为枚举可选值:
single-image-template、multi-image-template,发布内容时直接选中对应模板即可。也可以配置 Contentful 字段校验规则,根据上传的图片数量、富文本块数量自动赋值,避免人工操作出错。 - 如果不想改动现有内容模型,也可以跳过这一步,后续直接在 Gatsby 中通过文章的图片数量、富文本块数量判断匹配模板。
步骤2:Gatsby 端适配逻辑
方案A:通过 gatsby-node.js 动态匹配模板(适合原教程中用 createPages API 生成页面的场景)
- 调整
createPages方法中的 GraphQL 查询,新增模板类型字段(或者图片、富文本块数组字段用于判断),循环创建页面时根据字段值动态传入对应模板路径,示例代码如下:
exports.createPages = async ({ graphql, actions }) => { const { createPage } = actions // 查询所有博客文章 const result = await graphql(` query { allContentfulBlogPost { nodes { slug templateType # 不需要额外加字段的话,就查图片和富文本字段 # images { id } # contentBlocks { id } } } } `) // 循环创建页面 result.data.allContentfulBlogPost.nodes.forEach(post => { // 动态匹配模板路径 const templatePath = post.templateType === 'single-image-template' ? require.resolve('./src/templates/single-image-blog.js') : require.resolve('./src/templates/multi-image-blog.js') // 不需要加额外字段的话,用以下判断逻辑即可 // const templatePath = post.images.length > 1 || post.contentBlocks.length >1 // ? require.resolve('./src/templates/multi-image-blog.js') // : require.resolve('./src/templates/single-image-blog.js') createPage({ path: `/blog/${post.slug}`, component: templatePath, context: { slug: post.slug } }) }) }
方案B:通过文件系统路由API条件渲染(适合用自动路由生成页面的场景)
- 直接在路由文件
src/pages/blog/{contentfulBlogPost.slug}.js中做条件判断,渲染对应模板组件,示例代码如下:
import SingleImageTemplate from '../../components/SingleImageTemplate' import MultiImageTemplate from '../../components/MultiImageTemplate' const BlogPost = ({ data }) => { const post = data.contentfulBlogPost return post.templateType === 'single-image-template' ? ( <SingleImageTemplate post={post} /> ) : ( <MultiImageTemplate post={post} /> ) } export const query = graphql` query($slug: String!) { contentfulBlogPost(slug: {eq: $slug}) { title templateType # 其他业务需要的字段 } } ` export default BlogPost
两种方案都不会改动你要求的
/blog/文章标识URL 结构,优先推荐新增模板类型字段的方案,后续要新增更多模板时拓展性更强,不需要修改判断逻辑,直接新增枚举值和对应模板文件即可。
内容的提问来源于stack exchange,提问作者Tjm92
相关产品推荐
相关产品推荐

