У меня есть несколько вопросов по настройке схемы.
[
{
"name": "Foo Bar",
"slug": "foo-bar"
},
{
"name": "Fuz Baz",
"slug": "fuz-baz"
}
]
...
mapping: {
"MarkdownRemark.frontmatter.author": `AuthorsJson.alias`,
"MarkdownRemark.frontmatter.category": `CategoriesJson.name`
}
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);
}
Основной вопрос заключается в том, как мне выполнить валидацию переднего плана?
categories.json
(например, они не могут создать свою собственную категорию)?Спасибо!
Вот что у меня есть в 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/ и замените indexOf == -1
на более семантический includes
.
В остальном подход мне кажется вполне солидным, хороший способ.
If front matter is an array, how do I ensure that no more than 3 elements exist in the array?
По умолчанию (и так и должно быть) frontmatter
всегда будет объектом.