我们从Wordpress后端引入一些帖子,有些有图片(在ACF字段中),有些则没有。问题是盖茨比根据它收到的第一个节点推断出架构。如果它收到没有图片的节点,那么架构是错误的。
Where does Gatsby’s GraphQL schema come from? 使用Gatsby,我们使用从不同来源获取数据的插件。然后,我们使用该数据自动推断GraphQL架构。
我们怎样才能为GraphQL / Gatsby指定一个总是包含图片的模式,如果它是空白的话,将'null'作为默认值?
{
allWordpressWpTestimonial {
edges {
node {
id
title
acf {
photo_fields {
photo {
id
localFile {
childImageSharp {
sizes {
src
}
}
}
}
}
}
}
}
}
}
在上面的例子中,有时候“照片”不存在,它会破坏一切......
Gatsby config:
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',
],
}
答案 0 :(得分:3)
自这篇文章以来已经有一段时间了,但是自2.2 Gatsby has added a new API版以来,这使自定义架构变得更加容易。这不是wordpress的示例,而是gatsby的gatsby-transformer-remark
的示例,但我确定它是适用的。
我有一堆.md
,其前题如下:
---
title: "Screen title"
image: "./hero-image.png" <--- sometimes it's an empty string, ""
category: "Cat"
---
...content...
如果盖茨比首先以空白图片进入.md
,即使该字段应该为String
,也会错误地将该字段推断为File
。使用新的API,我可以将gatsby-node.js
中的图片字段告诉Gatsby:
exports.sourceNodes = ({ actions, schema }) => {
const { createTypes } = actions
createTypes(`
type MarkdownRemarkFrontmatter {
image: File
}
type MarkdownRemark implements Node {
frontmatter: MarkdownRemarkFrontmatter
}
`)
}
这将确保image
字段始终为文件类型,否则将为null
。
一些注意事项:
MarkdownRemark
这样的根节点必须实现Node
MarkdownRemarkFrontmatter
类型,然后将其传递到frontmatter
节点中的MarkdownRemark
字段。category
中指定MarkdownRemarkFrontmatter
字段,因此Gatsby会像以前一样推断出该字段。MarkdownRemark
,MarkdownRemarkFrontmatter
)的最有用方法是在graphiql中查找它们(默认为localhost:8000/___graphql
)答案 1 :(得分:0)
首先,您使用的是Gatsby-plugin-sharp,Gatsby-transform-sharp和Gatsby-source-WordPress插件吗?
我的网站使用Gatsby-source-Wordpress插件以及Sharp库以及Bluebird来返回承诺等。 在Post.js或Page.js上定义ImageURL。当将源URL加载到我的媒体库中时,会产生源URL,但由于我的WordPress网站是“以编程方式”构建的,因此已被卸载到S3存储桶中。 源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.使用图片网址查询退货。 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
}
}
}
}
`
希望这可以随时向我发送消息。
答案 2 :(得分:0)
有一个插件,很棒。我专门将其与Wordpress源插件一起使用。
请注意,您可能还需要在根目录中添加一个graphql.config.json
文件,以使IDE能够正确拾取它:
{
"schema": {
"file": "schema.json"
}
}