I'm having trouble with a datetime field in gatsby.
Originally I just used the string widget in netlify cms but markdown couldn't seem to decide what is a number and what's a string:
Which means gatsby sees conflicting field types:
warn There are conflicting field types in your data.
MarkdownRemark.frontmatter.startTime:
- type: number
value: 1080
- type: string
value: '07:00'
MarkdownRemark.frontmatter.endTime:
- type: number
value: 1140
- type: string
value: '08:00'
So I explicitly define them with the createTypes action as per gatsby's suggestion:
schema.buildObjectType({
name: 'Frontmatter',
fields: {
startTime: {
type: 'Date',
// resolve(parent){
// console.log(parent.startTime);
// },
extensions: {
dateformat: {
formatString: "HH:mm",
},
},
},
endTime: {
type: 'Date',
extensions: {
dateformat: {
formatString: "HH:mm",
},
}
},
},
}),
But that produces either 00:00 or "Invalid date"
I use the netlify timepicker to set the values:
- { label: "Start Time", name: startTime, widget: datetime, date_format: false, time_format: HH:mm, format: HH:mm}
- { label: "End Time", name: endTime, widget: datetime, date_format: false, time_format: HH:mm, format: HH:mm}
Is there a way I can force markdown to see strings instead of numbers? Or to see a datetime? Or get netlify cms to always save it as a string?
I have also had this problem and have discovered that the version of the YAML parser used by Gatsby (currently js-yaml#3.14.1) is parsing strings as base60 where possible. Which I believe is not compliant with the YAML 1.2 spec.
This issue has since been fixed in version 4 but unfortunately the libraries that Gatsby uses still depend on version 3. gatsby-transformer-remark#4.3.0 -> gray-matter#4.0.3 -> js-yaml#3.14.1
An attempt to force upgrade using npm-force-resolutions did not work but
fortunately gray-matter allow engines to be swapped using the options. Also gatsby-transformer-remark allows the gray-matter options to be configured within gatsby-config.js.
So I have managed to workaround the issue by installing js-yaml#4.1.0 and overriding the engine like so:
package.json
{
...
"dependencies": {
+ "js-yaml": "4.1.0",
gatsby-config.js
+ const yaml = require('js-yaml');
...
{
resolve: "gatsby-transformer-remark",
options: {
+ engines: {
+ yaml: {
+ parse: yaml.load.bind(yaml),
+ stringify: yaml.dump.bind(yaml)
+ }
},
Related
In Gatsby I'm trying to create a query with Graphql to query an image. The image location is set in a homepage.json file (this is being managed by Netlify CMS, so it is dynamic):
{
"homepage_text": "Here goes homepage text",
"homepage_background": "/images/homepage.jpg"
}
The images are located in src/images/
In Gatsby, there are 2 ways of displaying an image:
StaticImage (which doesn't work for me since the image is dynamic)
GatsbyImage
My only way is to use GatsbyImage I suppose, I query the homepage information with the following query:
query HomepageQuery {
file(ext: {eq: ".json"}, name: {eq: "homepage"}, childImageSharp: {}) {
childSettingsJson {
homepage_background
homepage_text
}
}
}
According to the gatsby-plugin-image docs https://www.gatsbyjs.com/plugins/gatsby-plugin-image I need to add the following to the query (childImageSharp and gatsbyImageData). But that's not possible with my example since it's not the actual image but rather the string that points to the location of the image. What can I change in my code/query to make it work along with GatsbyImage? (or another suggestion)
homepage_background {
childImageSharp {
gatsbyImageData(width: 200)
}
}
My config.yml:
backend:
name: git-gateway
branch: master # Branch to update (optional; defaults to master)
media_folder: static/images
public_folder: /images
collections:
- name: "settings"
label: "Settings"
delete: false # Prevent users from deleting documents in this collection
editor:
preview: false
files:
- name: "general"
label: "General"
file: "/content/settings/general.json"
description: "General"
fields:
- { label: "Website title", name: "site_title", widget: "string" }
- { label: "Favicon", name: "favicon", widget: "image" }
- name: "homepage"
label: "Home"
file: "/content/settings/homepage.json"
fields:
- { label: "Homepage Text", name: "homepage_text", widget: "string" }
- {
label: "Homepage Background Image",
name: "homepage_background",
widget: "image",
required: false,
}
Plugins from my gatsby-config.js:
plugins: [
`gatsby-plugin-image`,
`gatsby-plugin-netlify-cms`,
`gatsby-transformer-json`,
{
resolve: `gatsby-source-filesystem`,
options: {
name: `images`,
path: `${__dirname}/src/images`,
},
},
{
resolve: `gatsby-source-filesystem`,
options: {
name: `settings`,
path: `${__dirname}/content/settings`,
},
},
{
resolve: `gatsby-transformer-remark`,
options: {
plugins: [
`gatsby-remark-images`,
`gatsby-remark-responsive-iframe`,
`gatsby-remark-prismjs`,
],
},
},
`gatsby-transformer-sharp`,
`gatsby-plugin-sharp`,
`gatsby-plugin-postcss`,
`gatsby-plugin-sass`
],
As you pointed out, in order to use GatsbyImage you need to provide a valid node (childImageSharp) and in order to create it, you need to tell Gatsby where those images are.
To do so, you need to add a new instance of the gatsby-source-filesystem pointing to that path:
{
resolve: `gatsby-source-filesystem`,
options: {
name: `uploads`,
path: `${__dirname}/static/images`,
},
},
Now, when running gatsby develop, in your GraphiQL environment (localhost:8000/___graphql) you should see a new node called allImageSharp or allFile which can be filtered by sourceInstanceName (stands for the name in the gatsby-source-filesystem):
allFile(filter: { sourceInstanceName: { eq: "uploads" } }) {
edges {
node {
childImageSharp {
gatsbyImageData
}
}
}
}
There's a known issue where NetlifyCMS is not properly setting the relative paths properly and Gatsby is not able to infer directly the image node, hence the homepage_background still stands for a string rather than a Gatsby Image node data. Check https://github.com/danielmahon/gatsby-remark-relative-images
Disclaimer: ideally, NetlifyCMS is meant to source from a Markdown file, not a JSON, I don't know how this would behave in this approach.
I've got a simple schema:
export default {
title: 'hash schema',
version: 0,
primaryKey: 'hash',
type: 'object',
keyCompression: true,
properties: {
uuid: { type: 'string' },
id: { type: 'number' }
}
}
I want to have a table with a string field uuid as a primary key and I want to map it to an unique number that is automatically increased.
Is there a way to do so?
"automatically incrementing" doesn't sound very UUIDish to me. UUIDs are supposed to be random and unpredictable. You leave yourself vulnerable to the German Tank Problem
Nevertheless, you can indicate a string should be a UUID in JSON Schema by using "format": "uuid". It is only available in implementations supporting specification version draft2019-09 or later.
Below is a Contentful migration I wrote to create a content model called 'Trip' in Contentful. What I would like to do is specify the format of the "Start Date" and "End Date" fields. Contentful gives you three formatting options that can be set in the UI:
Date only
Date and time without timezone
Date and time with timezone
Without specifying the format in my migration file, I get format #3 by default and I need format #1. Anyone familiar with how to do this?
Thanks!
class CreateTrip < RevertableMigration
self.content_type_id = 'trip'
def up
with_space do |space|
# Create content model
content_type = space.content_types.create(
name: 'Trip',
id: content_type_id,
description: 'Content model for trip cards'
)
# Set validation
validation_for_country = Contentful::Management::Validation.new
validation_for_country.in = ['Bolivia','Haiti','India','Nicaragua', 'Puerto Rico', 'South Africa']
content_type.fields.create(id: 'image', name: 'Image', type: 'Link', link_type: 'Asset', required: true)
content_type.fields.create(id: 'country', name: 'Country', type: 'Symbol', required: true, validations: [validation_for_country])
content_type.fields.create(id: 'trip_details', name: 'Trip Details', type: 'Symbol')
content_type.fields.create(id: 'start_date', name: 'Start Date', type: 'Date', required: true)
content_type.fields.create(id: 'end_date', name: 'End Date', type: 'Date', required: true)
content_type.fields.create(id: 'trip_description', name: 'Trip Description', type: 'Text')
content_type.fields.create(id: 'link_url', name: 'Link URL', type: 'Symbol', required: true)
# Publish
content_type.save
content_type.publish
# Editor interface config
editor_interface = content_type.editor_interface.default
controls = editor_interface.controls
field = controls.detect { |e| e['fieldId'] == 'trip_details' }
field['settings'] = { 'helpText' => 'City, month, participant type, etc.' }
editor_interface.update(controls: controls)
editor_interface.reload
content_type.save
content_type.publish
end
end
end
When I export my content types using the contentful export command via the Contentful CLI, I can see something similar to this in my JSON:
{
"fieldId": "endDate",
"settings": {
"ampm": "24",
"format": "timeZ",
"helpText": "(Optional) The date and time when the event ends..."
},
"widgetId": "datePicker"
},
{
"fieldId": "internalTitle",
"widgetId": "singleLine"
},
{
"fieldId": "startDate",
"settings": {
"ampm": "24",
"format": "timeZ",
"helpText": "The date/time when this schedule starts..."
},
"widgetId": "datePicker"
}
Now, I don't use the Ruby migration tooling, but this leads me to believe you can set field['widgetId'] = 'datePicker' and
field['settings'] = {
'format' => 'dateonly',
'helpText' => ...
}
Let me know if that helps!
I am working on populating kendo--grid with APIs data but on adding validation on one field is automatically working for every other fields too.
Here is schema inside kendo-dataSource :
schema: {
model: {
id : "id",
fields: {
id: { editable: false, type: 'number'},
name: { editable: true, type : "string" },
unique_url: { editable: true , type: 'string'},
image_url : { editable: true, type : "string" },
title: {type : "string", validation: {
required: true,
validateTitle: function (input) {
console.log("I am inside validation",input.val());
if (input.val().length > 5) {
input.attr("data-validateTitle-msg", "Max length exceeded 5 characters only");
return false;
}
return true;
}
}
},
body: { editable: true, type : "string",validation: { max: 90, required: true, message : "Maximum characters should be 90"} },
adaccount_id: { editable: false, type: 'number'}
}
}
},
Here I have added validation for title field but its getting called for others fields too.
I am adding one snapshot of validation---
Please help me to find errors in it.
There isn't really any error in your code, but more like an error in Kendo Grid's validation design. Even though you specify the validation function only in the title field, it will run the validation globally for any input field that you edit.
In validateTitle you need to filter which input you want the validating function to run on. Something like this:
if (input.is("[name='title']") && input.val().length > 5) {
input.attr("data-validateTitle-msg", "Max length exceeded 5 characters only");
return false;
}
If you need a live working demo, you can always refer to Telerik's online demos that are editable, very handy for playing around with things. Here's the demo for custom validation where they similarly have to filter the input for the field name.
you want simply required field validation means just add your view model property attributes
[Required(ErrorMessage ="CountryCode is Mandatory")]
public virtual string CountryCode
{
get;
set;
}
We can easily set the maximum length using this code,It will not allow user to enter more characters than the specified one
model: {
id: "CLASSID",
fields: {
CLASSID: { type: "number" },
CLSNAME: { type: "string" },
CLSFLAG: {
type: "string", validation: {
required: true,maxlength:"3"
}
},
CLSSTATUS: { type: "boolean" }
}
}
Looking at the Kendo UI grid demos (ASP.NET MVC CSHTML flavor), when editing a cell that is bound to an numeric value, the input becomes a numerictextbox, but I can't seem to reproduce that behavior (on my side in stays a plain input). There must be something that assigns it the data-role attribute or something, but what is it ?
Thanks,
In order to use the model binding and have Kendo automatically assign the respective control, you need to setup a MVC editor template (http://coding-in.net/asp-net-mvc-3-how-to-use-editortemplates/) , i.e. Views/Shared/EditorTemplates. e.g. to render a Kendo NumericTextBox, create an editor template along these lines:
#model int
#(Html.Kendo().NumericTextBox())
Define the field type as numeric in the schema.
Example: Check UnitPrice or UnitsInStock
schema: {
model: {
id: "ProductID",
fields: {
ProductID: { editable: false, nullable: true },
ProductName: { validation: { required: true } },
UnitPrice: { type: "number", validation: { required: true, min: 1} },
Discontinued: { type: "boolean" },
UnitsInStock: { type: "number", validation: { min: 0, required: true } }
}
}
}
Kendo provides some templates under shared/EditorTemplates => here is Integer.cshtml template is ther. we can use that to show numeric value in a column. We need to set the EditorTemplateName property on column of the Grid.
EditorTemplateName("Integer") on column.Bound for that column.