作者:dmcm0005 | 来源:互联网 | 2022-12-07 19:14
我有一个gatsby网站,其中包含内容丰富的插件和graphql查询(安装程序正在运行)。
[编辑]我的gatsby安装程序使用pageCreate功能动态提取数据。并填充我的模板组件,这是我在下面共享的根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组件中。上面的查询和设置正在运行。
现在,我已经对“ Home”进行了硬编码,因为在创建灵活的可重用查询时遇到了麻烦。在创建模型时,我利用了contentful的灵活性,但是还没有找到在graphql查询中创建这种灵活性的方法。
我所知道的:
Graphql查询在运行时已解决,因此所有需要提取的内容都应该在该查询中。它不能是“动态的”。
问题: basicPageLayout中的“ Section”字段可以链接到任何内容类型。因此,我们可以混合和匹配粒度级别的内容类型。如何添加内容类型片段(如ContentTextAndImage与ContentText),使其适合该部分实例(查询中的“ Section”字段)?
换句话说,
我希望根查询获取“家”数据,该数据可能有4个部分,所有类型都是-ContentTextOverMedia,而“关于”数据可能也有4个部分,但类型交替-ContentText和ContentTextAndImage
这是目标,因为我想通过在内容上混合匹配内容类型来创建内容(页面),而无需每次创建新页面时都更新代码。这就是为什么Contentful有用并且首先被选中的原因。
到目前为止,我的想法是:
A.依次运行两个查询。一个在每个节上获取parent.id,并保存内容类型信息。其次,使用适当的片段获取数据。
B.通过Contentful API分别获取basicPageLayouts内容实例的JSON文件(例如“ Home”),然后使用该JSON文件创建要在每个实例中使用的graphql字符串(因此,Home,About等的布局不同)上),这需要更多的实验,不确定是否可行,也可能比需要的更复杂。
因此,请就我正在探索的上述路径或我未考虑使用graphql或gatsby功能的其他解决方案分享想法。
顺便说一句,这是我的第一个问题,我花了一些时间对其进行完善并尝试遵循指南,但是请务必在评论中给我反馈,以便即使您对我的问题没有答案也可以改善。提前致谢。
1> Khaled Garba..:
如果我正确理解,您想根据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 (Add you html here
)
}
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部分尚未经过测试,但希望您能理解。
更新:要有一个灵活的查询,而不是让您的内容类型作为单个引用字段,您可以有一个名为sections的字段,并且可以按所需顺序在其中添加所需的部分。您的查询将如下所示
export const pageQuery = graphql`
query basicPageQuery($pageName: String!) {
contentfulBasicPageLayout(pageName: {eq: $pageName}) {
sections {
... on ContentfulHeroFields {
internal {
type
}
}
}
}
哈立德