[英]How to give Gatsby a GraphQL schema
我们从Wordpress后端引入一些帖子,有些有图片(在ACF字段中),有些则没有。 问题是盖茨比根据它收到的第一个节点推断出架构。 如果它收到没有图片的节点,那么架构是错误的。
Gatsby的GraphQL架构来自哪里? 使用Gatsby,我们使用从不同来源获取数据的插件。 然后,我们使用该数据自动推断GraphQL架构。
我们怎样才能为GraphQL / Gatsby指定一个总是包含图片的模式,如果它是空白的话,将'null'作为默认值?
{
allWordpressWpTestimonial {
edges {
node {
id
title
acf {
photo_fields {
photo {
id
localFile {
childImageSharp {
sizes {
src
}
}
}
}
}
}
}
}
}
}
在上面的例子中,有时候“照片”不存在,它会破坏一切......
盖茨比配置:
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',
],
}
自从这篇文章发布以来已经有一段时间了,但是从版本2.2开始, Gatsby已经添加了一个新的API ,它将使定制架构变得更加容易。 这不是wordpress的例子,而是gatsby的gatsby-transformer-remark
,但我确信它是适用的。
我有一堆带有frontmatter的.md
看起来像这样:
---
title: "Screen title"
image: "./hero-image.png" <--- sometimes it's an empty string, ""
category: "Cat"
---
...content...
如果Gatsby首先使用空图像到达.md
,它将错误地将该字段推断为String
,即使它应该是File
。 使用新的API,我可以告诉盖茨比关于gatsby-node.js
图像字段:
exports.sourceNodes = ({ actions, schema }) => {
const { createTypes } = actions
createTypes(`
type MarkdownRemarkFrontmatter {
image: File
}
type MarkdownRemark implements Node {
frontmatter: MarkdownRemarkFrontmatter
}
`)
}
这将保证image
字段始终为文件类型,否则它将为null
。
一些说明:
MarkdownRemark
这样的根节点必须实现Node
MarkdownRemarkFrontmatter
类型,然后将其传递给MarkdownRemark
节点中的frontmatter
字段。 MarkdownRemarkFrontmatter
指定category
字段,因此Gatsby将像以前一样推断出它。 MarkdownRemark
, MarkdownRemarkFrontmatter
)最有用的方法是在graphiql中查找它们(默认为localhost:8000/___graphql
) 首先是你使用Gatsby-plugin-sharp,Gatsby-transform-sharp和Gatsby-source-WordPress插件?
我的网站使用Gatsby-source-Wordpress插件加上尖锐的库以及Bluebird来返回承诺等。在Post.js或Page.js上定义ImageURL。 源URL在我的媒体库中加载时生成,但是被卸载到S3存储桶,因为我的WordPress网站是“以编程方式”构建的。 源URL通常由您定义,并且在构建页面模板的帖子时可以在ACF字段类型中选择。
export const pageQuery = graphql`
query homePageQuery {
site {
siteMetadata {
title
subtitle
description
}
}
allWordpressPost(sort: { fields: [date] }) {
edges {
node {
title
excerpt
slug
type
_image{
source_url
}
categories {
slug
name
}
}
}
}
}
每个帖子类型都必须按照确切的顺序查询数据,否则GraphQL将无法正确返回方案,这将产生错误。 虽然听起来很简单并且重复,但有时会有两种不同的GraphQL方案和两种post.js示例post1.js和post2.js文件定义不同的帖子类别。 1.使用图像URL返回的查询。 2.没有图像的返回查询。 等于null或不存在这是GraphQL的垮台,它期望接收X,当Y发生时,它会变得不快乐并失败。
当你收到图像时,你也可以尝试使用sharp将其转换为href =并将其从https转换为接收时的大小。但在你的情况下,它将为null。 我们这样做是为了从旧的WordPress网站返回的员工生物页面。
/**
* Transform internal absolute link to relative.
*
* @param {string} string The HTML to run link replacemnt on
*/
linkReplace(string) {
// console.log(string)
const formatted = string.replace(
/(href="https?:\/\/dev-your-image-api\.pantheonsite\.io\/)/g,
`href="/`
)
return formatted
}
render() {
const post = { ...this.props.data.wordpressPost }
const headshot = { ...this.props.data.file.childImageSharp.resolutions }
const { percentScrolled } = { ...this.state }
const contentFormatted = this.linkReplace(post.content)
return (
<div ref={el => (this.post = el)}>
<div className={styles.progressBarWrapper}>
<div
style={{ width: `${percentScrolled}%` }}
className={styles.progressBar}
/>
</div>
<div className={styles.post}>
<h1
className={styles.title}
dangerouslySetInnerHTML={{ __html: post.title }}
/>
<div
className={styles.content}
dangerouslySetInnerHTML={{ __html: contentFormatted }}
/>
<Bio headshot={headshot} horizontal={true} />
</div>
</div>
)
}
}
Post.propTypes = {
data: PropTypes.object.isRequired,
}
export default Post
export const postQuery = graphql`
query currentPostQuery($id: String!) {
wordpressPost(id: { eq: $id }) {
wordpress_id
title
content
slug
}
file(relativePath: { eq: "your-image-headshot.jpg" }) {
childImageSharp {
resolutions(width: 300, height: 300) {
...GatsbyImageSharpResolutions
}
}
}
}
`
希望这有助于随时给我发消息。
有一个插件,它很棒。 我特意将它与Wordpress源插件一起使用。
请注意,您可能还需要将graphql.config.json
文件添加到根目录,以便IDE正确选择它:
{
"schema": {
"file": "schema.json"
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.