GraphQL查询盖茨比-使用灵​​活的内容模型进行内容丰富的设置

时间:2018-08-13 18:10:54

标签: graphql gatsby contentful

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

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

我的问题是我似乎遇到了一个局限性,或者只是不了解足够的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功能的其他解决方案的想法。

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

1 个答案:

答案 0 :(得分:5)

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

您可以使用Gatsbyjs Node API特别是distributed_cookie来实现这一目标。

在您的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 } } } 参数。 这样,您最终将创建所需的页面。 请注意:代码的react部分尚未经过测试,但希望您能理解。

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

$pageName

}

Khaled