Netlify CMS 不保存隐藏字段

Netlify CMS not saving hidden fields

问题 我正在使用 Netlify 和 Gatsby,实际上是在使用 this template 来学习这些系统。我可以在预制文件中看到 CMS 的 admin/config.yml 文件中有隐藏的小部件:

我正在尝试在 CMS 中创建一个包含一些小部件的新页面:

- file: "src/pages/sidebar/index.md"
    label: "Sidebar"
    name: "sidebar"
    fields:
      - { 
          label: "Template Key", 
          name: "templateKey", 
          widget: "hidden", 
          default: "sidebar-page",
        }
      - { label: Title, name: title, widget: string }
      - { label: Subtitle, name: subtitle, widget: string }
      - { label: Body, name: body, widget: markdown }
      - { label: Sidebar Title, name: sidebartitle, widget: string }
      - { label: Sidebar Content, name: sidebarcontent, widget: markdown }

普通字段都出现在CMS中,并且它们都被保存到我指定路径中的相应.md文件中。但是,隐藏字段没有被保存。这会导致构建失败,因为 GraphQL 正在尝试构建一个不存在的页面,因为隐藏的 templateKey 字段应该将其定向到适当的 Gatsby 组件。这只发生在我正在创建的新页面上。如果我从模板附带的页面中删除 templateKey 字段,当我在 CMS 中更新页面时,它会重新保存该隐藏字段。

我正在使用 netlify-cms-proxy-server,但即使我将 CMS 更新发送到我的远程仓库,隐藏字段也不会保存。

我只发现了其他一些与切线相关的内容的引用,这些都是几年前的,所以我怀疑我正在做的事情阻止了这些内容保存到我的新页面中。

如果我手动将 templateKey 字段添加到侧边栏页面的 .md 文件中,Gatsby 将编译并呈现页面。然后我可以在 CMS 中编辑页面,将新内容保存到 .md 文件,templateKey 字段将保留。保存新版本不会删除 templateKey 字段。

我还在模板的 github repository 上创建了一个问题,试图从相关人员那里获得一些见解。

这是我的 gatsby-config、gatsby-node 和 config.yml 文件,如果它们有用的话:

Netlify CMS 配置

backend:
  name: git-gateway
  branch: main
  commit_messages:
    create: "Create {{collection}} “{{slug}}”"
    update: "Update {{collection}} “{{slug}}”"
    delete: "Delete {{collection}} “{{slug}}”"
    uploadMedia: "[skip ci] Upload “{{path}}”"
    deleteMedia: "[skip ci] Delete “{{path}}”"

local_backend: true
media_folder: static/img
public_folder: /img

collections:
  - name: "blog"
    label: "Blog"
    folder: "src/pages/blog"
    create: true
    slug: "{{year}}-{{month}}-{{day}}-{{slug}}"
    fields:
      - {
          label: "Template Key",
          name: "templateKey",
          widget: "hidden",
          default: "blog-post",
        }
      - { label: "Title", name: "title", widget: "string" }
      - { label: "Publish Date", name: "date", widget: "datetime" }
      - { label: "Description", name: "description", widget: "text" }
      - { label: "Featured Post", name: "featuredpost", widget: "boolean" }
      - { label: "Featured Image", name: "featuredimage", widget: image }
      - { label: "Body", name: "body", widget: "markdown" }
      - { label: "Tags", name: "tags", widget: "list" }

  - name: "pages"
    label: "Pages"
    files:
      - file: "src/pages/index.md"
        label: "Landing Page"
        name: "index"
        fields:
          - {
              label: "Template Key",
              name: "templateKey",
              widget: "hidden",
              default: "index-page",
            }
          - { label: Title, name: title, widget: string }
          - { label: Image, name: image, widget: image }
          - { label: Heading, name: heading, widget: string }
          - { label: Subheading, name: subheading, widget: string }
          - {
              label: Mainpitch,
              name: mainpitch,
              widget: object,
              fields:
                [
                  { label: Title, name: title, widget: string },
                  { label: Description, name: description, widget: text },
                ],
            }
          - { label: Description, name: description, widget: string }
          - {
              label: Intro,
              name: intro,
              widget: object,
              fields:
                [
                  { label: Heading, name: heading, widget: string },
                  { label: Description, name: description, widget: text },
                  {
                    label: Blurbs,
                    name: blurbs,
                    widget: list,
                    fields:
                      [
                        { label: Image, name: image, widget: image },
                        { label: Text, name: text, widget: text },
                      ],
                  },
                ],
            }
          - {
              label: Main,
              name: main,
              widget: object,
              fields:
                [
                  { label: Heading, name: heading, widget: string },
                  { label: Description, name: description, widget: text },
                  {
                    label: Image1,
                    name: image1,
                    widget: object,
                    fields:
                      [
                        { label: Image, name: image, widget: image },
                        { label: Alt, name: alt, widget: string },
                      ],
                  },
                  {
                    label: Image2,
                    name: image2,
                    widget: object,
                    fields:
                      [
                        { label: Image, name: image, widget: image },
                        { label: Alt, name: alt, widget: string },
                      ],
                  },
                  {
                    label: Image3,
                    name: image3,
                    widget: object,
                    fields:
                      [
                        { label: Image, name: image, widget: image },
                        { label: Alt, name: alt, widget: string },
                      ],
                  },
                ],
            }
      - file: "src/pages/about/index.md"
        label: "About"
        name: "about"
        fields:
          - {
              label: "Template Key",
              name: "templateKey",
              widget: "hidden",
              default: "about-page",
            }
          - { label: "Title", name: "title", widget: "string" }
          - { label: "Body", name: "body", widget: "markdown" }
      - file: "src/pages/products/index.md"
        label: "Products Page"
        name: "products"
        fields:
          - {
              label: "Template Key",
              name: "templateKey",
              widget: "hidden",
              default: "product-page",
            }
          - { label: Title, name: title, widget: string }
          - { label: Image, name: image, widget: image }
          - { label: Heading, name: heading, widget: string }
          - { label: Description, name: description, widget: string }
          - {
              label: Intro,
              name: intro,
              widget: object,
              fields:
                [
                  { label: Heading, name: heading, widget: string },
                  { label: Description, name: description, widget: text },
                  {
                    label: Blurbs,
                    name: blurbs,
                    widget: list,
                    fields:
                      [
                        { label: Image, name: image, widget: image },
                        { label: Text, name: text, widget: text },
                      ],
                  },
                ],
            }
          - {
              label: Main,
              name: main,
              widget: object,
              fields:
                [
                  { label: Heading, name: heading, widget: string },
                  { label: Description, name: description, widget: text },
                  {
                    label: Image1,
                    name: image1,
                    widget: object,
                    fields:
                      [
                        { label: Image, name: image, widget: image },
                        { label: Alt, name: alt, widget: string },
                      ],
                  },
                  {
                    label: Image2,
                    name: image2,
                    widget: object,
                    fields:
                      [
                        { label: Image, name: image, widget: image },
                        { label: Alt, name: alt, widget: string },
                      ],
                  },
                  {
                    label: Image3,
                    name: image3,
                    widget: object,
                    fields:
                      [
                        { label: Image, name: image, widget: image },
                        { label: Alt, name: alt, widget: string },
                      ],
                  },
                ],
            }
          - {
              label: Testimonials,
              name: testimonials,
              widget: list,
              fields:
                [
                  { label: Quote, name: quote, widget: string },
                  { label: Author, name: author, widget: string },
                ],
            }
          - { label: Full_image, name: full_image, widget: image }
          - {
              label: Pricing,
              name: pricing,
              widget: object,
              fields:
                [
                  { label: Heading, name: heading, widget: string },
                  { label: Description, name: description, widget: string },
                  {
                    label: Plans,
                    name: plans,
                    widget: list,
                    fields:
                      [
                        { label: Plan, name: plan, widget: string },
                        { label: Price, name: price, widget: string },
                        {
                          label: Description,
                          name: description,
                          widget: string,
                        },
                        { label: Items, name: items, widget: list },
                      ],
                  },
                ],
            }
      - file: "src/pages/sidebar/index.md"
        label: "Sidebar"
        name: "sidebar"
        fields:
          - { 
              label: "Template Key", 
              name: "templateKey", 
              widget: "hidden", 
              default: "sidebar-page",
            }
          - { label: Title, name: title, widget: string }
          - { label: Subtitle, name: subtitle, widget: string }
          - { label: Body, name: body, widget: markdown }
          - { label: Sidebar Title, name: sidebartitle, widget: string }
          - { label: Sidebar Content, name: sidebarcontent, widget: markdown }

盖茨比配置

module.exports = {
  siteMetadata: {
    title: "Gatsby + Netlify CMS Starter",
    description:
      "This repo contains an example business website that is built with Gatsby, and Netlify CMS.It follows the JAMstack architecture by using Git as a single source of truth, and Netlify for continuous deployment, and CDN distribution.",
  },
  plugins: [
    "gatsby-plugin-react-helmet",
    {
      resolve: "gatsby-plugin-sass",
      options: {
        sassOptions: {
          indentedSyntax: false,
        },
      },
    },
    {
      // keep as first gatsby-source-filesystem plugin for gatsby image support
      resolve: "gatsby-source-filesystem",
      options: {
        path: `${__dirname}/static/img`,
        name: "uploads",
      },
    },
    {
      resolve: "gatsby-source-filesystem",
      options: {
        path: `${__dirname}/src/pages`,
        name: "pages",
      },
    },
    {
      resolve: "gatsby-source-filesystem",
      options: {
        path: `${__dirname}/src/img`,
        name: "images",
      },
    },
    `gatsby-plugin-image`,
    "gatsby-plugin-sharp",
    "gatsby-transformer-sharp",
    {
      resolve: "gatsby-transformer-remark",
      options: {
        plugins: [
          {
            resolve: "gatsby-remark-relative-images",
            options: {
              name: "uploads",
            },
          },
          {
            resolve: "gatsby-remark-images",
            options: {
              // It's important to specify the maxWidth (in pixels) of
              // the content container as this plugin uses this as the
              // base for generating different widths of each image.
              maxWidth: 2048,
            },
          },
          {
            resolve: "gatsby-remark-copy-linked-files",
            options: {
              destinationDir: "static",
            },
          },
        ],
      },
    },
    {
      resolve: "gatsby-plugin-netlify-cms",
      options: {
        modulePath: `${__dirname}/src/cms/cms.js`,
      },
    },
    {
      resolve: "gatsby-plugin-purgecss", // purges all unused/unreferenced css rules
      options: {
        develop: true, // Activates purging in npm run develop
        purgeOnly: ["/style.scss"], // applies purging only on the bulma css file
      },
    }, // must be after other CSS plugins
    "gatsby-plugin-netlify", // make sure to keep it last in the array
  ],
};

盖茨比节点

const _ = require('lodash')
const path = require('path')
const { createFilePath } = require('gatsby-source-filesystem')
const { fmImagesToRelative } = require('gatsby-remark-relative-images')

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

  return graphql(`
    {
      allMarkdownRemark(limit: 1000) {
        edges {
          node {
            id
            fields {
              slug
            }
            frontmatter {
              tags
              templateKey
            }
          }
        }
      }
    }
  `).then((result) => {
    if (result.errors) {
      result.errors.forEach((e) => console.error(e.toString()))
      return Promise.reject(result.errors)
    }

    const posts = result.data.allMarkdownRemark.edges

    posts.forEach((edge) => {
      const id = edge.node.id
      createPage({
        path: edge.node.fields.slug,
        tags: edge.node.frontmatter.tags,
        component: path.resolve(
          `src/templates/${String(edge.node.frontmatter.templateKey)}.js`
        ),
        // additional data can be passed via context
        context: {
          id,
        },
      })
    })

    // Tag pages:
    let tags = []
    // Iterate through each post, putting all found tags into `tags`
    posts.forEach((edge) => {
      if (_.get(edge, `node.frontmatter.tags`)) {
        tags = tags.concat(edge.node.frontmatter.tags)
      }
    })
    // Eliminate duplicate tags
    tags = _.uniq(tags)

    // Make tag pages
    tags.forEach((tag) => {
      const tagPath = `/tags/${_.kebabCase(tag)}/`

      createPage({
        path: tagPath,
        component: path.resolve(`src/templates/tags.js`),
        context: {
          tag,
        },
      })
    })
  })
}

exports.onCreateNode = ({ node, actions, getNode }) => {
  const { createNodeField } = actions
  fmImagesToRelative(node) // convert image paths for gatsby images

  if (node.internal.type === `MarkdownRemark`) {
    const value = createFilePath({ node, getNode })
    createNodeField({
      name: `slug`,
      node,
      value,
    })
  }
}

https://www.netlifycms.org/docs/widgets/hidden/ 目前

文件 collections 不支持隐藏的小部件