如何在GatsbyJS中处理markdown帖子的两级父子层级关系
可直接落地的轻量实现方案(无需复杂Schema定制,兼容Gatsby 2.x版本)
方案核心:通过gatsby-node.js的onCreateNode钩子预打标记,替代业务代码中的路径解析
你只需要在项目根目录的gatsby-node.js中增加十几行代码,给每个Markdown节点提前打上层级标记,后续所有查询和判断都可以直接使用预生成的字段,完全不需要反复解析fileAbsolutePath或slug:
exports.onCreateNode = ({ node, actions }) => { const { createNodeField } = actions // 仅处理Markdown文件节点 if (node.internal.type === `MarkdownRemark`) { const filePath = node.fileAbsolutePath // 标记当前节点是父产品还是变体 const isVariant = filePath.includes(`/Variants/`) createNodeField({ node, name: `productType`, value: isVariant ? `variant` : `parent` }) // 变体节点额外绑定对应的父产品标识,后续查询直接用 if (isVariant) { // 此处逻辑可以和你生成slug的逻辑对齐,示例是提取父产品的文件夹名 const parentProductId = filePath.match(/\/([^/]+)\/Variants\//)[1] createNodeField({ node, name: `parentProductId`, value: parentProductId }) } } }
各场景使用方式
1. 首页双模式展示
- 折叠模式:先查询所有
productType: parent的父产品节点,再按parentProductId匹配对应变体,直接统计变体数量即可,无需路径筛选 - 展开模式:直接查询所有MarkdownRemark节点,按需求做扁平化输出即可
查询示例:
allMarkdownRemark { edges { node { fields { slug productType parentProductId } excerpt frontmatter { title } } } }
2. 产品详情页逻辑判断
直接读取节点的productType字段即可:
- 若为
parent:查询所有parentProductId等于当前产品id的变体节点,渲染变体列表 - 若为
variant:查询对应父产品的信息,渲染子级产品专属的设计和内容
指定父产品的变体查询示例:
allMarkdownRemark(filter: {fields: {parentProductId: {eq: "Product_A"}, productType: {eq: "variant"}}}) { edges { node { fields { slug } frontmatter { title } } } }
更极简的替代方案(适合产品数量少的小型项目)
如果不想修改gatsby-node.js配置,也可以直接在每个Markdown文件的Frontmatter中手动加两个字段:
--- title: 变体1 productType: variant parentProductId: Product_A ---
后续所有查询逻辑和上面的方案完全一致,零配置改动,只需要新增文章时补全两个字段即可。
内容的提问来源于stack exchange,提问作者Mark Vital
相关产品推荐
相关产品推荐

