GraphQL:覆盖 slug
GraphQL: Overriding slugs
我正在用 Gatsby 开始我的第一个项目并且 运行 遇到了查询数据的问题 "may" 并不总是存在。这是我的 gatsby-node.js
文件:
const path = require('path');
const _ = require('lodash');
// Lifecycle methods
function attachFieldsToBlogPost({ node, actions }) {
if (node.internal.type !== 'MarkdownRemark') {
return;
}
const { createNodeField } = actions;
const { slug, title } = node.frontmatter;
const postPath = slug || _.kebabCase(title);
createNodeField({
node,
name: 'slug',
getter: node => node.frontmatter.slug, // eslint-disable-line no-shadow
value: postPath,
});
createNodeField({
node,
name: 'url',
value: postPath,
});
}
exports.onCreateNode = function() { // eslint-disable-line func-names
return Promise.all([attachFieldsToBlogPost].map(fn => fn.apply(this, arguments))); // eslint-disable-line prefer-rest-params
};
// Implementations
function getMarkdownQuery({ regex } = {}) {
return `
{
allMarkdownRemark(
sort: { fields: [frontmatter___date], order: DESC }
filter: { fileAbsolutePath: { regex: "${regex}" } }
) {
totalCount
edges {
node {
fileAbsolutePath
excerpt(pruneLength: 280)
timeToRead
frontmatter {
title
date
slug
}
fields {
url
slug
}
}
}
}
}
`;
}
function createBlogPostPages({ edges, createPage }) {
const component = path.resolve('src/templates/Post.js');
edges.forEach(({ node }) => {
const { slug, title } = node.frontmatter;
const postPath = slug || _.kebabCase(title);
createPage({
path: postPath,
component,
context: {
slug: postPath,
},
});
});
}
exports.createPages = async({ actions, graphql }) => {
const results = await Promise.all([
graphql(getMarkdownQuery({ regex: '/src/posts/' })),
]);
const error = results.filter(r => r.errors);
if (error.length) {
return Promise.reject(error[0].errors);
}
const [blogPostResults] = results;
const { createPage } = actions;
const blogPostEdges = blogPostResults.data.allMarkdownRemark.edges;
createBlogPostPages({
createPage,
edges: blogPostEdges,
});
};
而我的示例博客post内容是:
---
title: 'Hello world there'
date: '2018-08-25'
---
Here is some content.
```javascript
console.log('test')
```
当我提供 slug
frontmatter 组件时,页面会按预期创建。但是,我只想在 slug
参数可用时使用它(因此检查 frontmatter 在 attachFieldsToBlogPost
和 createBlogPostPages
中是否可用)。如果我删除 slug
frontmatter 项,我会收到以下错误:
GraphQLError: Cannot query field "slug" on type "frontmatter".
有没有办法覆盖用于创建 post 页面的路径 "if" slug
frontmatter 在那里?
希望这不会太模糊,因为这是我的第一个 Gatsby 项目,但似乎是一个非常有用的功能。谢谢!
如果您删除所有 slug
的情况,那么该字段将不再存在于 Gatsby 的内部架构中。您可能 运行 the issue described here.
只要您有至少 1 个带有 slug
字段的 markdown 文件,那么它就会存在于 Gatsby 的自动化 GraphQL 模式中,然后您的条件逻辑应该可以工作。
我正在用 Gatsby 开始我的第一个项目并且 运行 遇到了查询数据的问题 "may" 并不总是存在。这是我的 gatsby-node.js
文件:
const path = require('path');
const _ = require('lodash');
// Lifecycle methods
function attachFieldsToBlogPost({ node, actions }) {
if (node.internal.type !== 'MarkdownRemark') {
return;
}
const { createNodeField } = actions;
const { slug, title } = node.frontmatter;
const postPath = slug || _.kebabCase(title);
createNodeField({
node,
name: 'slug',
getter: node => node.frontmatter.slug, // eslint-disable-line no-shadow
value: postPath,
});
createNodeField({
node,
name: 'url',
value: postPath,
});
}
exports.onCreateNode = function() { // eslint-disable-line func-names
return Promise.all([attachFieldsToBlogPost].map(fn => fn.apply(this, arguments))); // eslint-disable-line prefer-rest-params
};
// Implementations
function getMarkdownQuery({ regex } = {}) {
return `
{
allMarkdownRemark(
sort: { fields: [frontmatter___date], order: DESC }
filter: { fileAbsolutePath: { regex: "${regex}" } }
) {
totalCount
edges {
node {
fileAbsolutePath
excerpt(pruneLength: 280)
timeToRead
frontmatter {
title
date
slug
}
fields {
url
slug
}
}
}
}
}
`;
}
function createBlogPostPages({ edges, createPage }) {
const component = path.resolve('src/templates/Post.js');
edges.forEach(({ node }) => {
const { slug, title } = node.frontmatter;
const postPath = slug || _.kebabCase(title);
createPage({
path: postPath,
component,
context: {
slug: postPath,
},
});
});
}
exports.createPages = async({ actions, graphql }) => {
const results = await Promise.all([
graphql(getMarkdownQuery({ regex: '/src/posts/' })),
]);
const error = results.filter(r => r.errors);
if (error.length) {
return Promise.reject(error[0].errors);
}
const [blogPostResults] = results;
const { createPage } = actions;
const blogPostEdges = blogPostResults.data.allMarkdownRemark.edges;
createBlogPostPages({
createPage,
edges: blogPostEdges,
});
};
而我的示例博客post内容是:
---
title: 'Hello world there'
date: '2018-08-25'
---
Here is some content.
```javascript
console.log('test')
```
当我提供 slug
frontmatter 组件时,页面会按预期创建。但是,我只想在 slug
参数可用时使用它(因此检查 frontmatter 在 attachFieldsToBlogPost
和 createBlogPostPages
中是否可用)。如果我删除 slug
frontmatter 项,我会收到以下错误:
GraphQLError: Cannot query field "slug" on type "frontmatter".
有没有办法覆盖用于创建 post 页面的路径 "if" slug
frontmatter 在那里?
希望这不会太模糊,因为这是我的第一个 Gatsby 项目,但似乎是一个非常有用的功能。谢谢!
如果您删除所有 slug
的情况,那么该字段将不再存在于 Gatsby 的内部架构中。您可能 运行 the issue described here.
只要您有至少 1 个带有 slug
字段的 markdown 文件,那么它就会存在于 Gatsby 的自动化 GraphQL 模式中,然后您的条件逻辑应该可以工作。