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



我有一个盖茨比网站,里面有内容丰富的插件graphql查询(设置正在工作(。

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

我的问题是关于我似乎遇到的一个限制,或者只是对 grpahql 还不够了解来理解这一点。

我的高级内容模型"BasicPageLayout"包含通过字段"部分"对其他内容类型的引用。因此,它在"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
}
}
}

内容类型片段全部位于重新指定的 UI 组件中。 上述查询和设置正在工作。

现在,我有"主页"硬编码,因为我在创建灵活的可重用查询时遇到问题。我在创建模型时利用了内容灵活性,但还没有找到在 graphql 查询中创建这种灵活性的方法。

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

问题:基本页面布局中的"分区"字段可以链接到任何内容类型。因此,我们可以混合和匹配粒度级别的内容类型。如何添加内容类型片段(如内容文本和图像与内容文本(,使其适合该部分实例(查询中的"部分"字段(?

换句话说,我希望根查询获取"主页"数据,该数据可能有 4 个部分,所有类型 - ContentTextOverMedia 以及"关于"数据,这些数据可能也有 4 个部分但具有交替类型 - 内容文本和内容文本和图像

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

到目前为止,我的想法:

A. 连续运行两个查询。一个获取每个部分的 parent.id,其中包含内容类型信息。Second 使用适当的片段获取数据。

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

所以,请分享一下我正在探索的上述路径的想法,或者我还没有考虑过使用 graphql 或 gatsby 功能的其他解决方案。

这是我关于SO btw的第一个问题,我花了一些时间来完善它并尝试遵循指南,但请在评论中给我反馈,以便即使您没有回答我的问题,我也可以改进。 提前谢谢。

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

您可以使用 Gatsbyjs Node 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
}
}
}

请注意创建页面时传递给组件上下文的$pageName参数。 这样,您最终将创建任意数量的页面。 请注意:代码的反应部分没有经过测试,但我希望你明白这个想法。

更新: 若要进行灵活的查询,而不是将内容类型作为单个引用字段,可以有一个名为 sections 的字段,并且可以按所需的顺序添加所需的部分。 您的查询将如下所示

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

}

卡莱德

相关内容

  • 没有找到相关文章

最新更新