Wordpressバックエンドからいくつかの投稿を取り込みます。一部は(ACFフィールドに)写真があり、一部はありません。問題は、Gatsbyが最初のノードに基づいてスキーマを推測することです。画像のないノードを受信した場合、スキーマは間違っています。
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
の例ですが、適用できると確信しています。
.md
がたくさんあり、frontmatterは次のようになっています。
---
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
フィールドを指定しなかったため、以前と同じようにギャツビーによって推測されます。MarkdownRemark
、MarkdownRemarkFrontmatter
)を見つける最も役立つ方法は、graphiqlでそれらを探すことです(localhost:8000/___graphql
のデフォルト)。まず、Gatsby-plugin-sharp、Gatsby-transform-sharp、およびGatsby-source-WordPressプラグインを使用していますか?
私のサイトでは、Gatsby-source-WordpressプラグインとSharpライブラリのほか、Promiseを返すためのBluebirdを使用しています。Post.jsまたはPage.jsでImageURLを定義します。ソースURLは、メディアライブラリに読み込まれたときに生成されますが、my 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はスキームを正しく返さず、エラーが発生します。簡単に聞こえ、重複しているため、同時に2つの異なるGraphQLスキーマと、異なる投稿カテゴリを定義する2つのpost.jsサンプルpost1.jsおよびpost2.jsファイルが必要になります。 1.画像のURLで返品を照会します。 2.画像なしで返品を照会します。 nullまたは存在しないことこれは、GraphQLの欠点であり、Xを受信することを期待し、Yが発生すると、不幸になり失敗します。
画像を受け取ったときにこれを試して、シャープで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ソースプラグインで使用しています。
IDEを正しく取得するには、graphql.config.json
ファイルをルートディレクトリに追加する必要がある場合があります。
{
"schema": {
"file": "schema.json"
}
}