盖茨比前端验证
Gatsby Frontmatter Validation
我有几个关于架构自定义的问题。
data/categories.json
[
{
"name": "Foo Bar",
"slug": "foo-bar"
},
{
"name": "Fuz Baz",
"slug": "fuz-baz"
}
]
盖茨比-config.js
...
mapping: {
"MarkdownRemark.frontmatter.author": `AuthorsJson.alias`,
"MarkdownRemark.frontmatter.category": `CategoriesJson.name`
}
盖茨比-node.js
exports.createSchemaCustomization = ({ actions, schema }) => {
const { createTypes } = actions;
const typeDefs = [
`type AuthorsJson implements Node @dontInfer {
alias: String,
name: String
slug: String,
bio: String,
profile: String
posts: [MarkdownRemark] @link(by: "frontmatter.author.alias", from: "alias")
}`,
`type CategoriesJson implements Node @dontInfer {
name: String,
slug: String,
posts: [MarkdownRemark] @link(by: "frontmatter.category.name", from: "name")
}`,
];
createTypes(typeDefs);
}
最重要的问题是,我如何完成 frontmatter 验证?
- 根据上面的问题,我如何强制每个post提供一个类别并且该类别必须存在于
categories.json
中(例如他们可以'自己编类)?
- 如果front matter是一个数组,如何保证数组中的元素不超过3个?
谢谢!
选项 1:
这是我在 gatsby-node.js
中的内容:
var categories = [];
var aliases = [];
exports.onCreateNode = ({ node, getNode, actions }) => {
const { createNodeField } = actions
if(node.internal.type === `CategoriesJson`) {
categories.push(node.name);
}
if(node.internal.type === `AuthorsJson`) {
aliases.push(node.alias);
}
if (node.internal.type === `MarkdownRemark`) {
const slug = createFilePath({ node, getNode, basePath: `pages` })
createNodeField({
node,
name: `slug`,
value: slug,
})
if (node.frontmatter.author === null || node.frontmatter.author === undefined) {
throw "Page is missing alias: " + node.fileAbsolutePath;
}
if (aliases.indexOf(node.frontmatter.author) == -1) {
throw "Page has invalid alias: " + node.fileAbsolutePath;
}
if (node.frontmatter.category === null || node.frontmatter.category === undefined) {
throw "Page is missing category: " + node.fileAbsolutePath;
}
if (categories.indexOf(node.frontmatter.category) == -1) {
throw "Page has invalid category ('" + node.frontmatter.category +"'): " + node.fileAbsolutePath;
}
if (node.frontmatter.tags.length > 3) {
throw "Page has more than 3 tags: " + node.fileAbsolutePath;
}
}
}
有没有更好的方法?
您可以通过以下方式简化所有条件:
let categories = [];
let aliases = [];
exports.onCreateNode = ({ node, getNode, actions }) => {
const { createNodeField } = actions
if(node.internal.type === `CategoriesJson`) {
categories.push(node.name);
}
if(node.internal.type === `AuthorsJson`) {
aliases.push(node.alias);
}
if (node.internal.type === `MarkdownRemark`) {
const slug = createFilePath({ node, getNode, basePath: `pages` })
createNodeField({
node,
name: `slug`,
value: slug,
})
if (!node.frontmatter.author || !aliases.includes(node.frontmatter.author)) {
throw "Page is missing alias: " + node.fileAbsolutePath;
}
if (!node.frontmatter.category || !categories.includes(node.frontmatter.category)) {
throw "Page is missing category: " + node.fileAbsolutePath;
}
if (node.frontmatter.tags.length > 3) {
throw "Page has more than 3 tags: " + node.fileAbsolutePath;
}
}
}
我还添加了 let
而不是 var
,后者现在已被弃用。检查 https://www.javascripttutorial.net/es6/difference-between-var-and-let/ and replaced the indexOf == -1
for the more semantic includes
.
处的差异
其余的,我觉得这个方法很可靠,这是个好方法。
If front matter is an array, how do I ensure that no more than 3
elements exist in the array?
默认情况下(并且应该如此)frontmatter
将始终是一个对象。
我有几个关于架构自定义的问题。
data/categories.json
[
{
"name": "Foo Bar",
"slug": "foo-bar"
},
{
"name": "Fuz Baz",
"slug": "fuz-baz"
}
]
盖茨比-config.js
...
mapping: {
"MarkdownRemark.frontmatter.author": `AuthorsJson.alias`,
"MarkdownRemark.frontmatter.category": `CategoriesJson.name`
}
盖茨比-node.js
exports.createSchemaCustomization = ({ actions, schema }) => {
const { createTypes } = actions;
const typeDefs = [
`type AuthorsJson implements Node @dontInfer {
alias: String,
name: String
slug: String,
bio: String,
profile: String
posts: [MarkdownRemark] @link(by: "frontmatter.author.alias", from: "alias")
}`,
`type CategoriesJson implements Node @dontInfer {
name: String,
slug: String,
posts: [MarkdownRemark] @link(by: "frontmatter.category.name", from: "name")
}`,
];
createTypes(typeDefs);
}
最重要的问题是,我如何完成 frontmatter 验证?
- 根据上面的问题,我如何强制每个post提供一个类别并且该类别必须存在于
categories.json
中(例如他们可以'自己编类)? - 如果front matter是一个数组,如何保证数组中的元素不超过3个?
谢谢!
选项 1:
这是我在 gatsby-node.js
中的内容:
var categories = [];
var aliases = [];
exports.onCreateNode = ({ node, getNode, actions }) => {
const { createNodeField } = actions
if(node.internal.type === `CategoriesJson`) {
categories.push(node.name);
}
if(node.internal.type === `AuthorsJson`) {
aliases.push(node.alias);
}
if (node.internal.type === `MarkdownRemark`) {
const slug = createFilePath({ node, getNode, basePath: `pages` })
createNodeField({
node,
name: `slug`,
value: slug,
})
if (node.frontmatter.author === null || node.frontmatter.author === undefined) {
throw "Page is missing alias: " + node.fileAbsolutePath;
}
if (aliases.indexOf(node.frontmatter.author) == -1) {
throw "Page has invalid alias: " + node.fileAbsolutePath;
}
if (node.frontmatter.category === null || node.frontmatter.category === undefined) {
throw "Page is missing category: " + node.fileAbsolutePath;
}
if (categories.indexOf(node.frontmatter.category) == -1) {
throw "Page has invalid category ('" + node.frontmatter.category +"'): " + node.fileAbsolutePath;
}
if (node.frontmatter.tags.length > 3) {
throw "Page has more than 3 tags: " + node.fileAbsolutePath;
}
}
}
有没有更好的方法?
您可以通过以下方式简化所有条件:
let categories = [];
let aliases = [];
exports.onCreateNode = ({ node, getNode, actions }) => {
const { createNodeField } = actions
if(node.internal.type === `CategoriesJson`) {
categories.push(node.name);
}
if(node.internal.type === `AuthorsJson`) {
aliases.push(node.alias);
}
if (node.internal.type === `MarkdownRemark`) {
const slug = createFilePath({ node, getNode, basePath: `pages` })
createNodeField({
node,
name: `slug`,
value: slug,
})
if (!node.frontmatter.author || !aliases.includes(node.frontmatter.author)) {
throw "Page is missing alias: " + node.fileAbsolutePath;
}
if (!node.frontmatter.category || !categories.includes(node.frontmatter.category)) {
throw "Page is missing category: " + node.fileAbsolutePath;
}
if (node.frontmatter.tags.length > 3) {
throw "Page has more than 3 tags: " + node.fileAbsolutePath;
}
}
}
我还添加了 let
而不是 var
,后者现在已被弃用。检查 https://www.javascripttutorial.net/es6/difference-between-var-and-let/ and replaced the indexOf == -1
for the more semantic includes
.
其余的,我觉得这个方法很可靠,这是个好方法。
If front matter is an array, how do I ensure that no more than 3 elements exist in the array?
默认情况下(并且应该如此)frontmatter
将始终是一个对象。