如何在Netlify CMS与Gatsby间建立一对多关联及查询作者完整信息
解决Gatsby+Netlify CMS关联作者后无法获取完整frontmatter的问题
嘿,这个问题我之前也碰到过!现在你拿到的只是作者的title字符串,是因为Netlify CMS的relation组件默认存的是你指定的valueField值,而Gatsby不会自动帮你关联到对应的作者节点。要拿到完整的作者frontmatter,得做两步核心调整:
1. 修改Netlify CMS的relation配置,使用唯一标识符作为valueField
首先,把valueField从title换成作者集合里的唯一字段(比如slug),因为title可能存在重复的情况,slug更可靠。调整后的配置如下:
{ label: "Author", name: "author", widget: "relation", collection: "authors", searchFields: ["title", "firstName", "lastName"], valueField: "slug" // 换成作者的slug字段,确保每个作者的slug唯一 }
如果你的作者集合还没配置自动生成slug,可以在Netlify CMS的authors集合里加个slug widget,比如:
{ label: "Slug", name: "slug", widget: "slug", from: "title", required: true }
2. 在Gatsby中添加自定义Resolver,关联文章与作者节点
接下来需要在gatsby-node.js中写一个自定义的GraphQL resolver,把文章frontmatter里的author slug关联到对应的作者节点。假设你的文章和作者都是Markdown文件(如果用MDX就把MarkdownRemark换成Mdx):
exports.createResolvers = ({ createResolvers }) => { createResolvers({ MarkdownRemark: { author: { type: "MarkdownRemark", // 对应作者集合的节点类型 resolve: async (source, args, context, info) => { // 从文章frontmatter获取作者slug const authorSlug = source.frontmatter.author; // 查询匹配的作者节点 return context.nodeModel.findOne({ type: "MarkdownRemark", query: { filter: { fields: { slug: { eq: authorSlug } } } } }); } } } }); };
注意:如果你的作者slug是存在frontmatter里而不是fields字段下,就把
fields: { slug: ... }改成frontmatter: { slug: ... }。
3. 调整GraphQL查询,获取完整作者信息
现在你就可以在GraphiQL里嵌套查询作者的所有frontmatter字段了,示例查询:
query GetArticlesWithAuthors { allMarkdownRemark { nodes { frontmatter { title date author { frontmatter { firstName lastName bio avatar { childImageSharp { gatsbyImageData(width: 100) } } } } } } } }
最后提醒一下:如果之前已经发布了一些文章,需要重新编辑这些文章,在Netlify CMS里重新选择作者,让系统把author字段更新为slug值,这样新的Resolver才能正确关联。
内容的提问来源于stack exchange,提问作者Matt




