Как дать Gatsby схему GraphQL - PullRequest
0 голосов
/ 09 июня 2018

Мы добавляем некоторые посты из бэкэнда Wordpress, у некоторых есть картинки (в поле ACF), а у некоторых нет.Проблема в том, что Гэтсби выводит схему на основе первого полученного узла.Если он получает узел без изображения, то схема неверна.

Откуда берется схема GraphQL от Gatsby? В Gatsby мы используем плагины, которые извлекают данные из разных источников,Затем мы используем эти данные для автоматического вывода схемы GraphQL.

Как мы можем диктовать схему для GraphQL / Gatsby, которая всегда содержит изображение, с нулевым значением по умолчанию, если оно пустое?

{
  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',
  ],
}

Ответы [ 3 ]

0 голосов
/ 13 октября 2018

Для этого есть плагин, и он потрясающий.Я специально использую его с плагином исходного кода Wordpress.

Обратите внимание, что вам также может понадобиться добавить файл graphql.config.json в корневой каталог, чтобы ваша среда IDE правильно его подобрала:

{
  "schema": {
    "file": "schema.json"
  }
}
0 голосов
/ 06 апреля 2019

С момента этой публикации прошло некоторое время, но начиная с версии 2.2 Гэтсби добавил новый API , который значительно упростит настройку схемы.Это не пример с WordPress, но с 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:

exports.sourceNodes = ({ actions, schema }) => {
  const { createTypes } = actions
  createTypes(`
    type MarkdownRemarkFrontmatter {
      image: File
    }

    type MarkdownRemark implements Node {
      frontmatter: MarkdownRemarkFrontmatter
    }
  `)
}

Это гарантирует, что поле image всегда будет иметь тип файла, в противном случае оно будет null.

Некоторые примечания:

  • Корневые узлы, такие как MarkdownRemark, должны реализовывать Node
  • Узел может реализовывать несколько интерфейсов
  • Youдолжен «проложить свой путь» вниз к соответствующей области.В этом примере я должен объявить тип MarkdownRemarkFrontmatter, а затем передать его в поле frontmatter в узле MarkdownRemark.
  • Гэтсби выведет остальные поля, если они не указаны.В приведенном выше примере, поскольку я не указал поле category в MarkdownRemarkFrontmatter, оно будет выведено Гэтсби, как и раньше.
  • Самый полезный способ найти эти типы (MarkdownRemark,MarkdownRemarkFrontmatter) - искать их в графике (по умолчанию localhost:8000/___graphql)
0 голосов
/ 24 июня 2018

Во-первых, используете ли вы плагины Gatsby-plugin-sharp, Gatsby-transform-sharp & Gatsby-source-WordPress?

Мой сайт использует плагин Gatsby-source-Wordpress плюс библиотеку Sharp, а также Bluebird длявозврат обещаний и т. д. Определите ImageURL в ваших Post.js или Page.js.Исходный 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 и два файла post1.js, например, post1.js и post2.js, определяющие разные категории записей.1. Запрос на возврат с изображениями URL.2. Запрос на возврат без изображений.равно нулю или не существует Это падение 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
                }
            }
        }
    }

`

Надеюсь, это поможет вам написать мне сообщение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...