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

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

问题描述

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

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

我的 gatsby 设置使用 pageCreate 功能动态提取数据.并填充我的模板组件,即我在下面分享的根 graphql 查询.如果 contentful 页面遵循以下查询中给出的结构,我可以使用设置创建多个页面.[/编辑]

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"包含通过字段Section"对其他内容类型的引用.因此,在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.

现在,我对主页"进行了硬编码,因为我无法创建灵活的可重用查询.我在创建模型时利用了 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),使其适用于该部分实例(查询中的部分"字段)?

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 上混合匹配内容类型来创建内容(页面),而无需在每次创建新页面时更新代码.这就是为什么 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 内容实例(例如Home")的 JSON 文件,并使用该 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 的第一个问题,我花了一些时间来改进它并尝试遵循指导方针,但请在评论中给我反馈,这样即使你没有我的答案,我也可以改进问题.提前致谢.

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 参数,它是在创建页面时传递给组件上下文的内容.这样,您最终将创建任意数量的页面.请注意:代码的反应部分没有经过测试,但我希望你能明白.

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.

更新:要进行灵活的查询,而不是将您的内容类型作为单个 ref 字段,您可以有一个称为部分的字段,您可以按照您想要的顺序在那里添加您想要的部分.您的查询将如下所示

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
        }
    }
}         

}

哈立德

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

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