Error when loading admin page of netlify cms - netlify

Error when loading the admin page on the Netlify CMS.
config must have required property ‘media_folder’
config must have required property ‘media_library’
config must match a schema in anyOf
I have media_folder and I thought that media_library isn’t a required field, or am I wrong.
my config.yml file looks like this
`
backend:
name: git-gateway
branch: main
media_folder: "public/images"
public_folder: "/images"
collections:
- name: "event"
label: "Event"
folder: "src/event"
create: true
slug: "{{year}}-{{month}}-{{day}}-{{slug}}"
fields:
- { label: "Event Title", name: "title", widget: "string" }
- { label: "Event Type", name: "type", widget: "string" }
- { label: "Event Description", name: "description", widget: "markdown" }
- { label: "Event Date", name: "date", widget: "datetime" }
`
Any help is appreciated

Related

Netlify CMS not saving hidden fields

Issue
I am using Netlify and Gatsby, actually working with this template to learn these systems. I can see in the pre-made files that there are hidden widgets in the admin/config.yml file for the CMS:
I am attempting create a new page with some widgets in the 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 }
The normal fields all appear in the CMS, and they all get saved to the appropriate .md file in the path that I specified. However, the hidden fields are not being saved. This is resulting in build failures because GraphQL is attempting to build a page that doesn't exist, since the hidden templateKey field is supposed to be directing it to the appropriate Gatsby component. This is only occurring for new pages that I am creating. If I remove the templateKey field from a page that came with the template, it will resave that hidden field when I update the page in the CMS.
I am using the netlify-cms-proxy-server, but even if I send the CMS updates to my remote repo, the hidden fields are not saved.
I only found a couple other references to things tangentially related, and those are from years ago, so I suspect that it's something that I am doing that's preventing these from saving for my new pages.
If I manually add the templateKey field into my sidebar page's .md file, Gatsby will compile and the page will render. I can then edit the page in the CMS, save new content to the .md file, and the templateKey field will remain. Saving a new version does not remove the templateKey field.
I have also created an Issue on the template's github repository to try and get some insight from those involved there.
Here is my gatsby-config, gatsby-node, and config.yml files as well, if those are helpful:
Netlify CMS Config
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 }
Gatsby Config
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
],
};
Gatsby Node
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/
The hidden widget is not supported for file collections at the moment

Problem with gatsby-node.js trying to create markdown pages hooked to NetlifyCMS

I am trying to solve this issue for days.
I never wrote a gatsby-node.js but used a Gatsby NetlifyCMS starter that came with it.
From what I understand it's probably supposed to create a page from my markdown data automatically.
When I add code to my static/admin/config.yml (the last bit), add content in the admin and pull, i get this error:
I would truly appreciate any help on this.
Your site's "gatsby-node.js" created a page with a component that
doesn't exist.
The path to the missing component is
"/home/hanna/Code/brnhrz-cms/src/templates/null.js"
The page object passed to createPage:
{
"path": "/events/events/",
"tags": null,
"component": "/home/hanna/Code/brnhrz-cms/src/templates/null.js",
"context": {
"id": "331ab6a0-648d-5ed0-9613-09abbdee8c18"
}
}
My config.yml:
backend:
name: git-gateway
branch: master
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/events/events.md"
label: "Events"
name: "events"
fields:
- {
label: "Template Key",
name: "templateKey",
widget: "hidden",
default: "events-page",
}
- { label: Title, name: title, widget: markdown }
- { label: Description, name: description, widget: markdown }
(...code for other pages that came already with the starter)
my gatsby-node.js:
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,
})
}
}
The fact that is complaining about:
"/home/hanna/Code/brnhrz-cms/src/templates/null.js"
Indicates that your component is null at:
component: path.resolve(
`src/templates/${String(edge.node.frontmatter.templateKey)}.js`
),
So ${String(edge.node.frontmatter.templateKey)} is null.
There are multiple possible sources that cause that issue. First of all, check the query in your GrahiQL environment to check that is returning a valid value in all the events you are creating because if one is null, it will break your code.
Also double-check the created markdown to see if it's properly formatted or it contains all the mandatory fields (specially the templateKey) and add it if it doesn't.

Azure custom connector dynamic schema not working

Trying to use x-ms-dynamic-values (which working as expected) and x-ms-dynamic-schema (which doesn't seems to work)
I only getting the body param name dynamicActionSchema instead of the dynamic schema.
Those are my paths:
paths:
/api/v1/actions:
get:
description: Get lists
summary: Get's action list you have access to
operationId: GetActionsList
parameters:
- {in: query, name: include_attributes, default: ref, type: string, description: The
number of items to skip before starting to collect the result set}
responses:
'200':
description: OK
schema: {$ref: '#/definitions/GetLists'}
/api/v1/actions/{actionId}:
get:
description: Gets the schema of the selected action
summary: Get's the schema of the selected action
operationId: GetActionSchema
parameters:
- {name: actionId, in: path, required: true, type: string, x-ms-summary: Select
Action}
responses:
'200':
description: OK
schema: {type: object}
/api/v1/executions/{action}:
post:
description: Executing ST action - Uses Dynamic values and dynamic schema to
draw form
summary: Executing ST action
operationId: ExecuteSTAction
parameters:
- name: action
type: string
in: path
description: Select action you want to execute
required: true
x-ms-summary: Select Action
x-ms-dynamic-values: {operationId: GetActionsList, value-path: ref}
- name: dynamicActionSchema
in: body
description: Dynamic Schema of items in selected action
schema:
type: object
x-ms-dynamic-schema:
operationId: GetActionSchema
parameters:
actionId: {parameter: action}
value-path: parameters
responses:
'201': {description: Executed}
definitions:
GetLists:
type: array
items:
type: object
properties:
ref: {type: string}
required: [ref]
security:
- API Key: []
Dynamic schema operation output sample:
{
"parameters": {
"tags": {
"description": "List of tags for item.",
"required": false,
"type": "array",
"position": 12
},
"env": {
"description": "Environment variables which will be available to the script.",
"type": "object"
},
"detected": {
"description": "The datetime for detecting the item.",
"required": true,
"type": "string",
"position": 6
},
"description": {
"description": "The description of the item.",
"required": false,
"type": "string",
"position": 2
}
...
}
}
Full example:
https://github.com/microsoft/PowerPlatformConnectors/blob/070009ba5681fd57ee6cc61d2a380123712a088f/certified-connectors/Ticketing.events/apiDefinition.swagger.json
MS docs:
https://learn.microsoft.com/en-us/connectors/custom-connectors/openapi-extensions#use-dynamic-schema
Open thread in Power Apps forum:
https://powerusers.microsoft.com/t5/Building-Power-Apps/Dynamic-schema-doesn-t-seems-to-work-based-on-a-body-parameter/m-p/1373866#M357492
Found my issue, schema should be in the form of:
{
"parameters": {
"type": "object",
"properties": {
"debug": {
"default": false,
"required": false,
"description": "Enable runner debug mode.",
"type": "boolean"
},
...
}
}
}

How to source just parent items in a select field on suitelet form (API 2.0)?

i am creating a suitelet form that will generate a pdf in POST. I need a field in my suitelet form, in which list of parent items can be selected(e.g. 1001 not 1001: 210-XL)for filtering purposes and all the items (child items) related to it can be printed in the PDF. Can anyone tell me what should i do?
It is not possible to add only Parent items in SELECT field on Suitelet.
You will need to add SELECT Field and then addSelectOption.
var select = form.addField({
id: 'selectfield',
type: serverWidget.FieldType.SELECT,
label: 'Select'
});
var itemSearchObj = search.create({
type: "item",
filters:
[
["parent.isinactive", "is", "F"],
"AND",
["formulatext: {parent}", "isnotempty", ""]
],
columns:
[
search.createColumn({
name: "parent",
summary: "GROUP",
label: "Parent"
}),
search.createColumn({
name: "internalid",
join: "parent",
summary: "GROUP",
label: "Internal ID"
})
]
});
itemSearchObj.run().each(function (result) {
select.addSelectOption({
value: result.getValue({
name: "parent",
summary: "GROUP",
label: "Parent"
}),
text: result.getValue({
name: "internalid",
join: "parent",
summary: "GROUP"
})
});
return true;
});
I hope, this will help.
You could try checking that the parent field is blank...? Not sure which record you are working with though, so that may or may not help.

Body parameters parsing issue with swagger-tool middleware (on expressJS)

With swagger 2.0 spec, i'm describing an 'operation' to add new resources:
A POST request with 3 parameters:
{
name: "username",
in: "header",
description: "New user unsername",
required: true,
type: "string"
},
{
name: "password",
in: "header",
description: "New user password",
required: true,
type: "string"
},
{
name: "pensis",
in: "body",
description: "New pensis to create",
required: true,
schema: {
properties: {
content: {
type: "string",
description: "Content of this pensis stored as markdown text"
}
}
}
}
I setup the POST request with the 3 previous parameters:
username: "Bob",
password: "Yo!",
pensis: {
content: "The content"
}
I send the POST request, and when i parse it using swagger-tool metadata 0.8.6 middleware, i get a strange response :
The value of req.swagger.params.pensis.value provided by this middleware is not:
{ content: 'The content' }
but:
{ content: 'The content',
username: 'ClementVidal',
password: 'r'
}
Do you have any idea about why those 3 parameters are merged together inside the same pensis object ??
Thanks for your help
Clément Vidal

Resources