我正在尝试在Gatsby网站上创建第二个博客模板。我只是开始学习Javascript,因此我需要gatsby-node.js文件的帮助。
我试图复制每行功能以本质上创建第二个博客模板,但是每次都失败,因此如果有人可以遍历我的代码并提供正确的功能,将非常有帮助。
我目前有一个“文章”模板,该模板可以成功运行。我要创建第二个“项目”模板。
这是我当前的gatsby-node.js文件,仅调用“文章”博客模板。
const path = require('path');
const { createFilePath } = require('gatsby-source-filesystem');
// Look at every node when it is created
exports.onCreateNode = ({node, getNode, actions}) => {
// Check for markdown nodes
const { createNodeField } = actions;
if(node.internal.type === 'MarkdownRemark') {
// Create a slug out of the markdown filepath name
const slug = createFilePath({
node,
getNode,
basePath: 'articles'
});
// Add the newly created slug to the node itself
createNodeField({
node,
name: 'slug',
value: `/article${slug}`
});
}
};
exports.createPages = ({ graphql, actions }) => {
const { createPage } = actions
return new Promise((resolve, reject) => {
graphql(`
{
allMarkdownRemark {
edges {
node {
fields {
slug
}
}
}
}
}
`).then(result => {
result.data.allMarkdownRemark.edges.forEach(({ node }) => {
createPage({
path: node.fields.slug,
component: path.resolve(`./src/templates/article.js`),
context: {
// Data passed to context is available in page queries as GraphQL variables.
slug: node.fields.slug,
},
})
})
resolve()
})
})
};
如何配置此文件以调用第二个博客模板(“项目”)?
答案 0 :(得分:2)
首先,您需要检索您的文章以及在graphql查询中获得的项目。您可以使用冒号重命名查询的一部分。我在您的allMarkdownRemark之前添加了articles:
。在生成的JSON中,allMarkdownRemark现在将称为“文章”。您可以在forEach循环中看到这一点,该循环现在遍历“ result.data.articles”。我还为所需的“项目”实体添加了查询。将它们重命名为文章和项目,使我们可以轻松地遍历每篇文章和每个项目,并为这些实体创建正确的页面。
项目查询现在是文章查询的副本。实际上,您应该在此处提供仅返回项目的查询,但我不知道您在哪里。然后为您在其中创建正确页面的项目和文章创建单独的循环。
exports.createPages = ({ graphql, actions }) => {
const { createPage } = actions
return new Promise((resolve, reject) => {
graphql(`{
articles: allMarkdownRemark {
edges {
node {
fields {
slug
}
}
}
}
projects: allMarkdownRemark {
edges {
node {
fields {
slug
}
}
}
}
}`).then(result => {
// In this loop we only take the articles returned by the query, and
// pass them to the src/templates/article.js component.
result.data.articles.edges.forEach(({ node }) => {
createPage({
// Rather than prepending every slug with '/article' in the
// createNodeField call, you can add it here to get more
// flexibility, and to allow different types to have different
// path prefixes.
path: `article/${node.fields.slug}`,
component: path.resolve(`./src/templates/article.js`),
context: {
slug: node.fields.slug,
},
})
})
// In this loop we do the same thing, only with the projects this
// time, and passing them to the project.js component I'm assuming
// you have. I've prepended the path with 'project/' to separate
// the projects from the articles.
result.data.projects.edges.forEach(({ node }) => {
createPage({
path: `project/${node.fields.slug}`,
component: path.resolve(`./src/templates/project.js`),
context: {
slug: node.fields.slug,
},
})
})
resolve()
})
})
};
我添加了一些缩进,以使事情更容易推理。我可能在此过程中犯了一些语法错误,所以请当心。
我注意到在您的onCreateNode
调用中,您将每个降价文件的标签设置为'article / $ {slug}`。如果您的项目也是markdown文件,则不应这样做,因为它还会使您的项目markdown文件以“ / article”开头。在上面的代码中,我在createPage调用中设置了正确的路径,而不是在createNodeField中。
您需要牢记的一件事是,如果您既将文章和项目都作为降价文件获得,则查询将很难区分它们。我通常解决此问题的方法是在前题中添加“类型”字段。因此,在您的情况下,您将:type: article
添加到所有文章的开头,type: project
添加到所有项目。最重要的部分是markdown文件顶部的三个虚线之间的部分:
---
type: article
name: something
etc, etc...
---
您可以像这样过滤您的markdown文件:
graphql(`query {
projects: allMarkdownRemark ( filter: {frontmatter: { type: { eq: "project" } } } ) {
edges {
node {
fields {
slug
}
}
}
}
}`);
这将仅返回具有project类型的markdown文件。对您的文章执行相同的操作。如果您使用Netlify CMS,则可以添加一个隐藏字段以自动添加正确的类型来帮助您进行过滤。
您可能要考虑将Promise更改为async / await调用。这是可选的,但我认为它使事情更容易阅读。在此处https://www.gatsbyjs.org/tutorial/part-seven/#creating-pages中查看gatsby的教程,以获取createPages API中异步/等待的示例。