GraphQL查询Gatsby-具有灵活内容模型的内容丰富的设置 [英] GraphQL queries for Gatsby - Contentful setup with a flexible content model

查看:60
本文介绍了GraphQL查询Gatsby-具有灵活内容模型的内容丰富的设置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 gatsby 网站,其中包含内容丰富的插件 graphql查询(设置正在运行).

I have a gatsby site with the contentful plugin and graphql queries (setup is working).

我的gatsby安装程序使用pageCreate功能动态提取数据.并填充我的模板组件,这是我在下面共享的根graphql查询.如果有关内容的页面遵循以下查询中给出的结构,则可以使用安装程序创建多个页面. [/EDIT]

My gatsby setup pulls data dynamically using the pageCreate feature. And populates my template component, the root graphql query of which I've shared below. I can create multiple pages using the setup if the pages on contentful follow the structure given in the below query. [/EDIT]

我的问题是我似乎遇到了一个局限性,或者只是不了解足够的grpahql来理解这一点.

My question is about a limitation I seemed to have come across or just don't know enough grpahql to understand this yet.

我的高级内容模型"BasicPageLayout"由对内容"字段的其他内容类型的引用组成.因此,在"BasicPageLayout"中包含哪些内容类型以及添加顺序方面,它很灵活.

My high level content model 'BasicPageLayout' consists of references to other content types through the field 'Section'. So, it's flexible in terms of which content types are contained in the 'BasicPageLayout' and the order in which they are added.

根页面查询

export const pageQuery = graphql`
query basicPageQuery {
contentfulBasicPageLayout(pageName: {eq: "Home"}) {

    heroSection {
        parent {
            id
        }
        ...HeroFields
    }

    section1 {
        parent {
            id
        }
        ...ContentText

    }

    section2 {
        parent {
            id
        }
        ...ContentTextOverMedia
    }

    section3 {
        parent {
            id
        }
        ...ContentTextAndImage
    }

    section4 {
        parent {
            id
        }
        ...ContentText
    }
  }
}

内容类型将所有片段都存储在相应的UI组件中. 上面的查询和设置正在运行.

The content type fragments all live in the respecitve UI components. The above query and setup are working.

现在,我已经对"Home"进行了硬编码,因为在创建灵活的可重用查询时遇到了麻烦.创建模型时,我利用了contentful的灵活性,但是还没有找到在graphql查询中创建这种灵活性的方法.

Now, I have "Home" Hard coded because I'm having trouble creating a flexible reusable query. I'm taking advantage of contentful's flexible nature when creating the models, but haven't found a way to create that flexibility in the graphql query for it.

我所知道的: Graphql查询在运行时已解决,因此所有需要获取的内容都应该在该查询中.它不能是动态的".

What I do know: Graphql query is resolved at run time, so everything that needs to be fetched should be in that query. It can't be 'dynamic'.

问题:basicPageLayout中的"Section"字段可以链接到任何内容类型.因此,我们可以混合和匹配粒度级别的内容类型.如何添加内容类型片段(如ContentTextAndImage与ContentText),使其适合该部分实例(查询中的"Section"字段)?

Issue: The 'Section' fields in the basicPageLayout can link to any content type. So we can mix and match the granular level content types. How do I add the content type fragment (like ContentTextAndImage vs ContentText) so it is appropriate for that section instance ('Section' field in the query)?

换句话说 我想让根查询获取主页"数据,该数据可能有4个部分,所有类型都是-ContentTextOverMedia 以及关于"数据(可能也有4个部分,但具有交替的类型-ContentText和ContentTextAndImage

In other words I'd like the root query to get 'Home' data which might have 4 sections, all of type - ContentTextOverMedia as well as 'About ' data that might have also have 4 sections but with alternating types - ContentText and ContentTextAndImage

这是目标,因为我想通过在内容上混合匹配内容类型来创建内容(页面),而无需在每次创建新页面时都更新代码.这就是为什么Contentful有用并且首先被选中的原因.

This is the goal because I want to create content (Pages) by mix-matching content types on contentful, without needing to update the code each time a new Page is created. Which is why Contentful is useful and was picked in the first place.

到目前为止我的想法:

A.依次运行两个查询.一个在每个节上获取parent.id,其中包含内容类型信息.其次,使用适当的片段获取数据.

A. Run two queries, in series. One fetches the parent.id on each section and that holds the content type info. Second fetches the data using the appropriate fragment.

B.通过Contentful API分别获取basicPageLayouts内容实例的JSON文件(例如"Home"),然后使用该JSON文件创建要在每个实例中使用的graphql字符串(因此,Home,About等的布局不同) 这需要更多的实验,不确定它是否可行,还可能比需要的更复杂.

B. Fetch the JSON file of the basicPageLayouts content instance (such as 'Home') separately through Contentful API, and using that JSON file create the graphql string to be used in each instance (So, different layout for Home, About, and so on) This needs more experimentation, not sure if it's viable, could also be more complex then it needs to be.

因此,请分享关于我正在探索的上述路径的想法,或者是我未考虑使用graphql或gatsby功能的其他解决方案的想法.

So, please share thoughts on the above paths that I'm exploring or another solution that I haven't considered using graphql or gatsby's features.

这是我关于SO BTW的第一个问题,我花了一些时间来完善它并尝试遵循指南,但请务必在评论中给我反馈,以便即使您没有答案也可以改善我的情况.问题. 预先感谢.

This is my first question on SO btw, I've spent some time on refining it and trying to follow the guidelines but please do give me feedback in comments so I can improve even if you don't have an answer to my question. Thanks in advance.

推荐答案

如果我正确理解,您希望根据Contentful的数据动态创建页面.

If I understood correctly you want to create pages dynamically from the data coming from Contentful.

您可以使用Gatsbyjs Node API特别是createPage来实现.

You can achieve this using the Gatsbyjs Node API specifically createPage.

在您的gatsby-node.js文件中,您可以拥有这样的内容

In your gatsby-node.js file you can have something like this

const fs = require('fs-extra')
const path = require('path')

exports.createPages = ({graphql, boundActionCreators}) => {
  const {createPage} = boundActionCreators
  return new Promise((resolve, reject) => {
    const landingPageTemplate = path.resolve('src/templates/landing-page.js')
    resolve(
      graphql(`
        {
          allContentfulBesicPageLayout {
            edges {
              node {
                pageName
              }
            }
          }
        }
      `).then((result) => {
        if (result.errors) {
          reject(result.errors)
        }
        result.data.allContentfulBesicPageLayout.edges.forEach((edge) => {
          createPage ({
            path: `${edge.node.pageName}`,
            component: landingPageTemplate,
            context: {
              slug: edge.node.pageName // this will passed to each page gatsby create
            }
          })
        })
        return
      })
    )
  })
}

现在在您的src/templates/landing-page.js

import React, { Component } from 'react'
const LandingPage = ({data}) => {
    return (<div>Add you html here</div>)

}
export const pageQuery = graphql`
query basicPageQuery($pageName: String!) {
contentfulBasicPageLayout(pageName: {eq:  $pageName}) {

    heroSection {
        parent {
            id
        }
        ...HeroFields
    }

    section1 {
        parent {
            id
        }
        ...ContentText

    }

    section2 {
        parent {
            id
        }
        ...ContentTextOverMedia
    }

    section3 {
        parent {
            id
        }
        ...ContentTextAndImage
    }

    section4 {
        parent {
            id
        }
        ...ContentText
    }
  }
}

请注意创建页面时传递给组件上下文的$pageName参数. 这样,您最终将创建所需的页面. 请注意:代码的react部分尚未经过测试,但希望您能理解.

note the $pageName param that's what was passed to the component context when creating a page. This way you will end up creating as many pages as you want. Please note: the react part of the code was not tested but I hope you get the idea.

更新: 要进行灵活的查询,您可以将一个字段称为sections,然后按所需的顺序在其中添加所需的部分,而不是将Content Types作为单个引用字段. 您的查询将如下所示

Update: To have a flexible query you instead of having your content Types as single ref field, you can have one field called sections and you can add the section you want there in the order you desire. Your query will look like this

    export const pageQuery = graphql`
    query basicPageQuery($pageName: String!) {
    contentfulBasicPageLayout(pageName: {eq:  $pageName}) {
       sections {
         ... on ContentfulHeroFields {
           internal {
              type
        }
    }
}         

}

Khaled

这篇关于GraphQL查询Gatsby-具有灵活内容模型的内容丰富的设置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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