Gatsby的GraphQL查询-具有灵活内容模型的内容设置

Gatsby的GraphQL查询-具有灵活内容模型的内容设置,graphql,gatsby,contentful,Graphql,Gatsby,Contentful,我有一个gatsby网站,有内容插件和图形查询(安装程序正在运行) [编辑] 我的盖茨比设置使用pageCreate功能动态提取数据。并填充我的模板组件,即我在下面共享的根graphql查询。如果contentful上的页面遵循下面查询中给出的结构,我可以使用设置创建多个页面。 [/编辑] 我的问题是关于我似乎遇到的一个限制,或者只是不知道足够的grpahql来理解这一点 我的高级内容模型“BasicPageLayout”包括通过字段“Section”引用其他内容类型。因此,它在“BasicPa

我有一个gatsby网站,有内容插件图形查询(安装程序正在运行)

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

我的问题是关于我似乎遇到的一个限制,或者只是不知道足够的grpahql来理解这一点

我的高级内容模型“BasicPageLayout”包括通过字段“Section”引用其他内容类型。因此,它在“BasicPageLayout”中包含哪些内容类型以及它们的添加顺序方面是灵活的

根页面查询

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
    }
  }
}
内容类型片段都位于Respectve UI组件中。 上述查询和设置正在运行

现在,我已经硬编码了“Home”,因为我在创建灵活的可重用查询时遇到了困难。我在创建模型时利用了contentful的灵活性,但还没有找到一种方法在graphql查询中为其创建这种灵活性

我所知道的: Graphql查询在运行时解析,所以需要获取的所有内容都应该在该查询中。它不可能是“动态的”

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

换句话说 我希望根查询获得“Home”数据,它可能有4个部分,全部类型为-ContentTextOverMedia 以及“关于”数据,这些数据可能也有4个部分,但具有交替类型-ContentText和ContentTextAndImage

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

我目前的想法:

A.连续运行两个查询。一个获取每个节上的parent.id,该节保存内容类型信息。第二步使用适当的片段获取数据

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

因此,请分享我正在探索的上述路径的想法,或者我没有考虑使用graphql或gatsby特性的另一个解决方案

这是我的第一个问题,顺便说一句,我花了一些时间来完善它,并试图遵循指导原则,但请务必在评论中给我反馈,这样即使你没有我的问题的答案,我也可以改进。
提前感谢。

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

您可以使用Gatsbyjs节点API来实现这一点,特别是
createPage

在您的
gatsby node.js文件中,您可以有如下内容

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


哈立德

谢谢你的回答,哈立德。当我开始这个项目时,我看了你的《满足的盖茨比》系列,它非常有用,所以也谢谢你。澄清:我已经让pageCreate工作了,如果我用完全相同的结构向contentful添加了多个页面,它就会动态工作。问题在于查询结构的灵活性。对于其他页面,我可能需要具有不同内容类型的节或具有不同顺序的节,但我希望使用相同的模板(布局),因为有内容的cao上的顺序/内容类型可能会经常更改。啊,好吧,那么,与其将内容类型作为单个引用字段,您可以有一个名为sections的字段,您可以按所需的顺序在其中添加所需的节。我将更新answerOk,使其成为一个单独的字段(multi-ref?),其中包含按所需顺序排列的所有部分——这也适用于组织内容和传达顺序。但是,关于如何识别每个节值是什么(什么内容类型)以便将其字段放入查询中的问题仍然存在。因为这些内容类型字段必须在运行时已知。如果问题需要更多信息,请告诉我!这是
的一部分。。。在Contentful[YourSectionContentType]
上,并基于internal.type渲染块。我在这里做了类似的事情:啊,所以对于每个节值,通过对每个片段使用“on”特性来覆盖任何已定义内容类型的可能性。太好了!谢谢你编辑答案。
    export const pageQuery = graphql`
    query basicPageQuery($pageName: String!) {
    contentfulBasicPageLayout(pageName: {eq:  $pageName}) {
       sections {
         ... on ContentfulHeroFields {
           internal {
              type
        }
    }
}