如何给Gatsby提供GraphQL模式 [英] How to give Gatsby a GraphQL schema
问题描述
我们从Wordpress后端引入了一些帖子,一些带有图片(在ACF字段中),有些则没有.问题在于,盖茨比根据接收到的第一个节点来推断模式.如果它接收到没有图片的节点,则说明架构是错误的.
We're bringing in some posts from a Wordpress backend, some have pictures (in an ACF field) and some don't. The problem is that Gatsby infers the schema based off of the first node it receives. If it receives a node without a picture, then the schema is wrong.
盖茨比的位置GraphQL模式来自何处?通过Gatsby,我们使用了从不同来源获取数据的插件.然后,我们使用该数据自动推断GraphQL模式.
Where does Gatsby’s GraphQL schema come from? With Gatsby, we use plugins which fetch data from different sources. We then use that data to automatically infer a GraphQL schema.
我们如何为GraphQL/Gatsby指示一个始终包含图片的模式,如果空白,则将'null'作为默认值?
How can we dictate a schema to GraphQL/Gatsby that always includes a picture, with 'null' as the default value if it's blank?
{
allWordpressWpTestimonial {
edges {
node {
id
title
acf {
photo_fields {
photo {
id
localFile {
childImageSharp {
sizes {
src
}
}
}
}
}
}
}
}
}
}
在上面的示例中,有时照片"不存在,并且会破坏所有内容...
In the example above, sometimes 'photo' doesn't exist and it breaks everything...
Gatsby配置:
const innertext = require('innertext')
const url = require('url')
module.exports = {
siteMetadata: {
title: 'Test',
googleMapsAPIKey: 'xxxxxx',
adminBaseUrl: '123.123.123',
adminProtocol: 'http',
},
pathPrefix: '/web/beta',
plugins: [
'gatsby-plugin-react-next',
'gatsby-plugin-react-helmet',
'gatsby-plugin-sharp',
'gatsby-plugin-svgr',
{
resolve: 'gatsby-plugin-google-analytics',
options: {
trackingId: 'GOOGLE_ANALYTICS_TRACKING_ID',
},
},
{
resolve: 'gatsby-plugin-bugherd',
options: {
key: 'xxxxxx',
showInProduction: true,
},
},
{
resolve: '@andrew-codes/gatsby-plugin-elasticlunr-search',
options: {
fields: ['title', 'url', 'textContent', 'urlSearchable'],
resolvers: {
wordpress__PAGE: {
title: node => node.title,
textContent: node => innertext(node.content),
url: node => url.parse(node.link).path,
urlSearchable: node =>
url
.parse(node.link)
.path.split('/')
.join(' '),
},
wordpress__POST: {
title: node => node.title,
textContent: node => innertext(node.content),
url: node => `/news/${node.slug}`,
urlSearchable: node =>
url
.parse(node.link)
.path.split('/')
.join(' '),
},
wordpress__wp_industry: {
title: node => node.title,
textContent: node => innertext(node.content),
url: node => `/business/industries/${node.slug}`,
urlSearchable: node =>
url
.parse(node.link)
.path.split('/')
.join(' '),
},
},
},
},
{
resolve: 'gatsby-source-wordpress',
options: {
baseUrl: 'xxxxxx',
protocol: 'http',
hostingWPCOM: false,
useACF: true,
auth: {
htaccess_user: 'admin',
htaccess_pass: 'xxxxxx',
htaccess_sendImmediately: false,
},
verboseOutput: false,
},
},
'gatsby-transformer-sharp',
],
}
推荐答案
It's been awhile since this post, but since version 2.2 Gatsby has added a new API that'll make it much easier to customize schema. This is not an example with wordpress but with gatsby's gatsby-transformer-remark
, but I'm sure it's applicable.
我有一堆 .md
像这样:
---
title: "Screen title"
image: "./hero-image.png" <--- sometimes it's an empty string, ""
category: "Cat"
---
...content...
如果Gatsby首先以空白图片进入 .md
,则即使该字段应为 File <,它也会错误地将该字段推断为
String
./code>.使用新的API,我可以在 gatsby-node.js
中告诉盖茨比有关图像字段的信息:
If Gatsby get to the .md
with the empty image first, it'll incorrectly infer that field as String
, even though it should be File
. With the new API, I can tell Gatsby about image field in gatsby-node.js
:
exports.sourceNodes = ({ actions, schema }) => {
const { createTypes } = actions
createTypes(`
type MarkdownRemarkFrontmatter {
image: File
}
type MarkdownRemark implements Node {
frontmatter: MarkdownRemarkFrontmatter
}
`)
}
这将确保 image
字段始终为文件类型,否则将为 null
.
This'll guarantee the image
field to always be of File type, otherwise it'll be null
.
一些注意事项:
- 像
MarkdownRemark
这样的根节点必须实现Node
- 一个节点可以实现多个接口
- 您必须按照自己的方式行事至相关领域.在此示例中,我必须声明
MarkdownRemarkFrontmatter
类型,然后将其传递给MarkdownRemark
节点中的frontmatter
字段. - 如果未指定,Gatsby将推断其余字段.在上面的示例中,由于我没有在
MarkdownRemarkFrontmatter
中指定category
字段,因此Gatsby会像以前一样推断出该字段. - 找到这些类型(
MarkdownRemark
,MarkdownRemarkFrontmatter
)的最有用的方法是在graphiql中查找它们(默认为localhost:8000/___ graphql 代码>)
- Root nodes like
MarkdownRemark
has to implementNode
- A node can implement multiple interface
- You have to 'work your way' down to the relevant field. In this example, I have to declare the
MarkdownRemarkFrontmatter
type, then pass it to thefrontmatter
field inMarkdownRemark
node. - Gatsby will infer the rest of the fields if not specified. In the example above, since I didn't specify the
category
field inMarkdownRemarkFrontmatter
, it will be inferred by Gatsby just like before. - The most helpful way to find these types (
MarkdownRemark
,MarkdownRemarkFrontmatter
) is to look for them in graphiql (default atlocalhost:8000/___graphql
)
这篇关于如何给Gatsby提供GraphQL模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!