如何给 Gatsby 一个 GraphQL 模式 [英] How to give Gatsby a GraphQL schema

查看:40
本文介绍了如何给 Gatsby 一个 GraphQL 模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们从 Wordpress 后端引入了一些帖子,有些有图片(在 ACF 领域),有些没有.问题是 Gatsby 根据它接收到的第一个节点推断模式.如果它收到一个没有图片的节点,那么架构是错误的.

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 schema 来自哪里?在 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',
  ],
}

推荐答案

这篇文章已经有一段时间了,但从 2.2 版开始 Gatsby 添加了一个新的 API,这将使自定义架构变得更加容易.这不是 wordpress 的例子,而是 gatsby 的 gatsby-transformer-remark,但我确定它适用.

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 与 frontmatter 看起来像这样:

I have a bunch of .md with frontmatter looks like this:

---
title: "Screen title"
image: "./hero-image.png"  <--- sometimes it's an empty string, ""
category: "Cat"
---

...content...

如果 Gatsby 首先使用空图像访问 .md,它会错误地将该字段推断为 String,即使它应该是 File.使用新的 API,我可以将 gatsby-node.js 中的图像字段告诉 Gatsby:

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 字段始终为 File 类型,否则为 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 会像以前一样推断它.
  • 找到这些类型(MarkdownRemarkMarkdownRemarkFrontmatter)最有用的方法是在 graphiql 中寻找它们(默认在 localhost:8000/___graphql代码>)
  • Root nodes like MarkdownRemark has to implement Node
  • 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 the frontmatter field in MarkdownRemark node.
  • Gatsby will infer the rest of the fields if not specified. In the example above, since I didn't specify the category field in MarkdownRemarkFrontmatter, 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 at localhost:8000/___graphql)

这篇关于如何给 Gatsby 一个 GraphQL 模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆