如何在 Netlify CMS 和 Gatsby 之间建立一对多连接

How to make a one to many connection between Netlify CMS and Gatsby

我在 gatsby 网站上使用 Netlify CMS。我在 post collection 上使用了 netlify CMS 关系小部件来引用作者 collection 的标题字段,所以...

- {label: "Author", name: "author", widget: "relation", collection: "authors", searchFields: ["title", "firstName", "lastName"], valueField: "title"}

效果很好,但是当我在我的 GraphiQL 中进行查询时 window 唯一可用的字段是作者,只有一个字符串,我如何访问特定作者的所有 frontmatter?

事实证明,在 Netlify 中建立连接只是第一步。然后你需要配置你的 gatsby-node.js 文件来建立这些关系。最终结果允许您对具有嵌套作者的帖子进行查询。这是整个设置。

首先是我在 static/admin

中的 netlifyCMS config.yml
backend:
  name: git-gateway
  branch: development

media_folder: "static/images/uploads" # Media files will be stored in the repo under static/images/uploads
public_folder: "/images/uploads"

    collections:
  - name: "blog" # Used in routes, e.g., /admin/collections/blog
    label: "Blog" # Used in the UI
    folder: "src/pages/blog/posts" # The path to the folder where the documents are stored
    create: true # Allow users to create new documents in this collection
    slug: "{{year}}-{{month}}-{{day}}-{{slug}}" # Filename template, e.g., YYYY-MM-DD-title.md
    fields: # The fields for each document, usually in front matter
      - {label: "Layout", name: "layout", widget: "hidden", default: "blog"}
      - {label: "Author", name: "author", widget: "relation", collection: "authors", searchFields: ["title", "firstName", "lastName"], valueField: "title"}
      - {label: "Title", name: "title", widget: "string"}
      - {label: "Publish Date", name: "date", widget: "datetime"}
      - {label: "Featured Image", name: "thumbnail", widget: "image"}
      - {label: "Body", name: "body", widget: "markdown"}
  - name: "authors"
    label: "Authors"
    folder: "src/authors"
    create: true
    slug: "{{slug}}"
    fields: 
      - {label: "Layout", name: "layout", widget: "hidden", default: "author"}
      - {label: "Full Name", name: "title", widget: "string"}
      - {label: "First Name", name: "firstName", widget: "string"}
      - {label: "Last Name", name: "lastName", widget: "string"}
      - {label: "Position", name: "position", widget: "string"}
      - {label: "Profile Picture", name: "profilePicture", widget: "image"}
      - {label: "Email", name: "email", widget: "string"}

然后在我的 gatsby-node.js 文件的底部。

exports.sourceNodes = ({ boundActionCreators, getNodes, getNode }) => {
    const { createNodeField } = boundActionCreators;

    const postsOfAuthors = {};
    // iterate thorugh all markdown nodes to link books to author
    // and build author index
    const markdownNodes = getNodes()
        .filter(node => node.internal.type === "MarkdownRemark")
        .forEach(node => {
            if (node.frontmatter.author) {
                const authorNode = getNodes().find(
                    node2 =>
                        node2.internal.type === "MarkdownRemark" &&
            node2.frontmatter.title === node.frontmatter.author
                );

                if (authorNode) {
                    createNodeField({
                        node,
                        name: "author",
                        value: authorNode.id,
                    });

                    // if it's first time for this author init empty array for his posts
                    if (!(authorNode.id in postsOfAuthors)) {
                        postsOfAuthors[authorNode.id] = [];
                    }
                    // add book to this author
                    postsOfAuthors[authorNode.id].push(node.id);
                }
            }
        });

    Object.entries(postsOfAuthors).forEach(([authorNodeId, postIds]) => {
        createNodeField({
            node: getNode(authorNodeId),
            name: "posts",
            value: postIds,
        });
    });
};

最后在 gastby-config.js 中你需要添加映射。

    mapping: {
        "MarkdownRemark.fields.author": "MarkdownRemark",
        "MarkdownRemark.fields.posts": "MarkdownRemark",
    }

这使您能够像这样进行查询...

query AllPosts {
  allMarkdownRemark (
    filter: { fileAbsolutePath: {regex : "\/posts/"} },
    sort: {fields: [frontmatter___date], order: DESC}
  ){
    edges {
      node {
        fields {
          author {
            fields {
              slug
            }
            frontmatter {
              title
              firstName
              lastName
              profilePicture

            }
          }
          slug
        }
        frontmatter {
          title
          date(formatString:"MMM DD 'YY")
          thumbnail
          layout
        }
        excerpt
      }
    }
  }
}