Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(docs): Update sourcing from agility cms #30966

Merged
merged 36 commits into from
Apr 28, 2021
Merged
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
335f4f4
update agility cms docs
joshua-isaac Apr 20, 2021
5445317
Update docs/docs/sourcing-from-agilitycms.md
joshua-isaac Apr 21, 2021
11fdbde
Update docs/docs/sourcing-from-agilitycms.md
joshua-isaac Apr 21, 2021
5da619c
Update docs/docs/sourcing-from-agilitycms.md
joshua-isaac Apr 21, 2021
dfb88f5
Update docs/docs/sourcing-from-agilitycms.md
joshua-isaac Apr 21, 2021
ab5e1a3
Update docs/docs/sourcing-from-agilitycms.md
joshua-isaac Apr 21, 2021
d7cea7e
Update docs/docs/sourcing-from-agilitycms.md
joshua-isaac Apr 21, 2021
9d0294d
Update docs/docs/sourcing-from-agilitycms.md
joshua-isaac Apr 21, 2021
f7dcaa0
Update docs/docs/sourcing-from-agilitycms.md
joshua-isaac Apr 21, 2021
687dc48
Update docs/docs/sourcing-from-agilitycms.md
joshua-isaac Apr 21, 2021
bce21e6
Update docs/docs/sourcing-from-agilitycms.md
joshua-isaac Apr 21, 2021
925cee5
Update docs/docs/sourcing-from-agilitycms.md
joshua-isaac Apr 21, 2021
b24691e
Update docs/docs/sourcing-from-agilitycms.md
joshua-isaac Apr 21, 2021
1f8d9fb
Update docs/docs/sourcing-from-agilitycms.md
joshua-isaac Apr 21, 2021
f12bdab
Update docs/docs/sourcing-from-agilitycms.md
joshua-isaac Apr 21, 2021
b6f30b1
Update docs/docs/sourcing-from-agilitycms.md
joshua-isaac Apr 21, 2021
90fc325
Update docs/docs/sourcing-from-agilitycms.md
joshua-isaac Apr 21, 2021
3e7bc1c
Update docs/docs/sourcing-from-agilitycms.md
joshua-isaac Apr 21, 2021
15c9e62
Update docs/docs/sourcing-from-agilitycms.md
joshua-isaac Apr 21, 2021
4785434
Update docs/docs/sourcing-from-agilitycms.md
joshua-isaac Apr 21, 2021
67cd3a7
Update sourcing-from-agilitycms.md
joshua-isaac Apr 21, 2021
420b3ea
Update docs/docs/sourcing-from-agilitycms.md
joshua-isaac Apr 21, 2021
d602a6d
Update sourcing-from-agilitycms.md
joshua-isaac Apr 21, 2021
5e01af8
Update docs/docs/sourcing-from-agilitycms.md
joshua-isaac Apr 27, 2021
59f691b
Update docs/docs/sourcing-from-agilitycms.md
joshua-isaac Apr 27, 2021
aa058ed
Update docs/docs/sourcing-from-agilitycms.md
joshua-isaac Apr 27, 2021
bafa7b3
Update docs/docs/sourcing-from-agilitycms.md
joshua-isaac Apr 27, 2021
e61f6e9
Update docs/docs/sourcing-from-agilitycms.md
joshua-isaac Apr 27, 2021
e77e58c
Update docs/docs/sourcing-from-agilitycms.md
joshua-isaac Apr 27, 2021
99a9bcb
Update docs/docs/sourcing-from-agilitycms.md
joshua-isaac Apr 27, 2021
d13aa64
Update docs/docs/sourcing-from-agilitycms.md
joshua-isaac Apr 27, 2021
c9cf88b
Update docs/docs/sourcing-from-agilitycms.md
joshua-isaac Apr 27, 2021
4dfe3b3
Update docs/docs/sourcing-from-agilitycms.md
joshua-isaac Apr 27, 2021
5d0139f
chore: format
Apr 28, 2021
5407a74
Update sourcing-from-agilitycms.md
LekoArts Apr 28, 2021
b54592e
Update sourcing-from-agilitycms.md
LekoArts Apr 28, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
312 changes: 275 additions & 37 deletions docs/docs/sourcing-from-agilitycms.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,38 +6,42 @@ This guide takes you through the steps involved in setting up a Gatsby site that

Check our [docs](https://help.agilitycms.com/hc/en-us/articles/360039879872) for up-to-date documentation.

## What is Agility CMS? What makes it different?
## What is Agility CMS?

[Agility CMS](https://agilitycms.com/) is a headless Content Management System (CMS) that lets you define your custom content types, relationships and pages. This is called Content Architecture, and you can reuse this content for your websites and apps.
[Agility CMS](https://agilitycms.com/) is a flexible headless Content Management System (CMS) with an infinite number of ways to configure and set up your pages and content. Agility lets you define custom content types, relationships and pages. This is called Content Architecture, and you can reuse this content for your websites and apps.

Agility believes that a successful website balances the **User Experience (UX)**, **Editor Experience (EX)**, and **Developer Experience (DX)**.

While Gatsby tends to handle **UX** and **DX** quite well, editors are not always comfortable working directly in a codebase. They prefer to manage their sitemap and see what content is on which pages. Using Gatsby with a headless CMS allows for this.
While Gatsby tends to handle **UX** and **DX** quite well, editors are not always comfortable working directly in a codebase. They prefer to manage their sitemap and see what content is on which pages. Using Gatsby with a headless CMS like Agility allows for this.

Agility aims to empower and improve the **Editor Experience** by providing built-in **Page Management**. This means developers can build UI Components and leave editors to compose their pages.
Agility aims to empower and improve the **Editor Experience** by providing built-in [**Page Management**](https://help.agilitycms.com/hc/en-us/articles/360055805831). This means developers can build UI Components and leave editors to compose their pages.

[Learn more about Agility CMS and Gatsby](https://help.agilitycms.com/hc/en-us/articles/360039879872)

## Getting started
## Getting Started

### Create a free Agility account
This guide walks you through the steps involved in setting up a Gatsby site that fetches content from Agility CMS.

Create an Agility CMS account with the Free Plan (this plan is free forever). [Sign up to Agility CMS](https://account.agilitycms.com/sign-up?product=agility-free).
### Step 1: Create a free Agility account

Once your account is created, you'll need to grab your GUID and API Keys.
In order to showcase best practices, evaluate, and help onboard new users when using Agility CMS, this guide uses the pre-configured Blog Template. This template has a few Pages along with some Page Modules and Content Models already set for you to help support a familiar blogging experience.

### Get the code
It's important to note though, that you can customize anything and everything in this template, it's just giving you a head start and serving as an example!

Create an Agility CMS account with the [**Free Developer Plan**](https://account.agilitycms.com/sign-up?product=agility-free) (this plan is free forever).

### Step 2: Get the code

Make sure you have the Gatsby CLI installed:

```shell
npm install -g gatsby-cli
```

Clone the [Agility CMS Gatsby Starter](https://github.com/agility/agility-gatsby-starter) repo from GitHub that has all the code you need to get started:
Create a new Gatsby project using the [Agility CMS Gatsby Starter](https://github.com/agility/agilitycms-gatsby-starter) repo from GitHub that has all the code you need to get started:

```shell
git clone https://github.com/agility/agility-gatsby-starter.git
gatsby new agilitycms-gatsby-starter https://github.com/agility/agilitycms-gatsby-starter
```

Install the dependencies:
Expand All @@ -46,52 +50,286 @@ Install the dependencies:
npm install
```

Once you've the infrastructure set up, run the site in development mode:
### Step 3: Authenticate your Gatsby site with Agility

Make a copy of `.env.development.example` file called `.env.development`.

```shell
gatsby develop
cp .env.development.example .env.development
```

The site is just a starter, but it has a bunch of interesting features that you can use to build from. The next step is to hook this code up to your new Agility CMS instance that you just created.
Add your `AGILITY_GUID` and `AGILITY_API_KEY` variable values to the `.env.development` file, you can find these in the Content Manager by going to [Settings](https://manager.agilitycms.com/settings/apikeys).

```text:title=.env.development
# Your Instance Id
AGILITY_GUID=

# Your Preview API Key (recommended) - you can get this from the Getting Started Page in Agility CMS. It starts with defaultpreview.
AGILITY_API_KEY=

# If using your Preview API Key, set this to true
AGILITY_API_ISPREVIEW=true
```

## Hook it up to your Agility CMS instance
### Step 4: Running the site locally

Edit the `gatsby-config.js` file and replace the `guid` and `apiKey` with yours.
Once your environment variables have been added for development, you can run the site locally:

You can find your API keys on the Getting Started page in the Agility CMS Content Manager.
```shell
gatsby develop
```

![Agility CMS - Dashboard - API Keys](./images/agilitycms-api-keys.png)
If successful, your site's build should complete and you be able to view the site in your browser on `http://localhost:8000`. You can also run the GraphiQL IDE at `http://localhost:8000/___graphql`. The GraphiQL IDE will help you explore the app’s data, including data from Agility.

If you use the `preview` key, you won't have to publish to see the changes you've made show up. If you use the `fetch` key, make sure you've published any content you wish to see changed.
For production, follow the same steps using the `.env.production` file and your Live API Key.

## How it works

The Gatsby Source Plugin will synchronize your sitemap, pages, and content for you and place it into **GraphQL**.
### Sourcing and Querying Agility Content in Gatsby

All of those pages and content are then made available in GraphQL to the React Components you will write to render those pages.
You can source content from Agility CMS into your Gatsby site with [`gatsby-source-agilitycms`](https://github.com/agility/gatsby-source-agilitycms) which will synchronize all of your content, page modules, sitemaps and pages, and make them available via GraphQL.

Check out the component called "Jumbotron". This is an example of how to display a styled heading and sub-heading with content that comes from Agility CMS. Here is the Module that provides this content being edited in the Agility CMS Content Manager:
The source plugin uses [`@agility/content-sync`](https://github.com/agility/agility-sync-sdk) which ensures that only content that has changed is updated. It keeps things in-sync for you. This means your first build will download all of your content, while subsequent builds only update what has changed. This enables incremental builds and results in bleeding-edge, fast build times.

![Agility CMS - Example Module - Jumbotron](./images/agilitycms-jumbotron.png)
To query content from Agility CMS, you would query `allAgility<contentTypeName>`, for example, `allAgilityPost`, then select what fields you want to retrieve for each item. An example can be seen here in the [agilitycms-gatsby-starter](https://github.com/agility/agilitycms-gatsby-starter/blob/main/src/components/agility-pageModules/PostsListing.jsx):

And here is the code used to render it. Notice that the `title` and `subTitle` fields are available as properties of the `item.fields` object.
```graphql
query {
posts: allAgilityPost {
nodes {
customFields {
title
date(formatString: "MMMM DD, YYYY")
image {
url
label
}
content
}
}
}
}
```

```jsx:title=src/modules/Jumbotron.js
import React, { Component } from "react"
import { graphql, StaticQuery } from "gatsby"
[Learn more about Sourcing and Querying Agility Content in Gatsby](https://help.agilitycms.com/hc/en-us/articles/360043003951)

### How Pages Work

The `gatsby-source-agilitycms` plugin makes it easy to source content, but it also generates your Pages for you based off of your sitemap in Agility CMS. This means that editors in the CMS control what pages are available, what their URLs are, and exactly what UI components (Agility CMS calls these Page Modules) make up each page.

Each page in Agility is composed and generated dynamically at _build-time_ using a **masterPageTemplate** that you define in your `gatsby-config.js` plugin options.

```js:title=gatsby-config.js
module.exports = {
siteMetadata: {
title: "Agility CMS Gatsby Starter",
},
plugins: [
...
{
//the name of the plugin
resolve: "@agility/gatsby-source-agilitycms",
//the options for our plugin
options: {
...
//the page template that will be used to render Agility CMS pages
masterPageTemplate: "./src/AgilityPage.jsx"
},
},
...
]
}
```

import "./Jumbotron.css"
```jsx:title=src/AgilityPage.jsx
import React from "react"
import { graphql } from "gatsby"

export const query = graphql`
query($pageID: Int!, $contentID: Int!, $languageCode: String!) {
agilitypage(languageCode: { eq: $languageCode }, itemID: { eq: $pageID }) {
pageJson
}
agilityitem(
languageCode: { eq: $languageCode }
itemID: { eq: $contentID }
) {
itemJson
}
}
`

const AgilityPage = ({ pageContext, data }) => {
return (
<>
<SEO
title={viewModel.page.title}
description={viewModel.page.seo.metaDescription}
keywords={viewModel.page.seo.metaKeywords}
ogImage={viewModel.dynamicPageItem?.customFields?.image?.url}
/>
<PreviewBar isPreview={viewModel.isPreview} />
<div id="site-wrapper" className="flex flex-col min-h-screen">
<SiteHeader
languageCode={viewModel.languageCode}
isMultiLanguage={viewModel.isMultiLanguage}
/>
<main className="flex-grow">
<AgilityPageTemplate {...viewModel} />
</main>
<SiteFooter />
</div>
</>
)
}

export default AgilityPage
```

[Learn more about How Agility Pages Work in Gatsby](https://help.agilitycms.com/hc/en-us/articles/360043035211)

### How Page Modules Work

Page Modules in Agility CMS are the functional components that make up a page. Editors use these to compose what type of content is on each page and in what order they appear. Developers define what page modules are available in the CMS and what fields they have. Each module defined in Agility CMS should correspond to a React Component in your Gatsby site.

In the [agilitycms-gatsby-starter](https://github.com/agility/agilitycms-gatsby-starter) site, the name of the page module is used to find a corresponding React component that matches the same name. If a match is found, that component is dynamically imported and rendered.

For example, if a module has a reference name of RichTextArea in the CMS, then while the page is being rendered by the gatsby-source-agilitycms plugin, it will look for `src/components/agility-pageModules/RichTextArea.jsx` in the `src/components/agility-pageModules` directory.

```jsx:title=src/components/agility-pageModules/RichTextArea.jsx
import React from "react"
import { renderHTML } from "../../agility/utils"

const RichTextArea = ({ module }) => {
// get module fields
const { customFields } = module

return (
<div className="relative px-8">
<div className="max-w-2xl mx-auto my-12 md:mt-18 lg:mt-20">
<div
className="prose max-w-full mx-auto"
dangerouslySetInnerHTML={renderHTML(customFields.textblob)}
/>
</div>
</div>
)
}

export default RichTextArea
```

export default class Jumbotron extends Component {
render() {
return (
<section className="jumbotron">
<h1>{this.props.item.fields.title}</h1>
<h2>{this.props.item.fields.subTitle}</h2>
</section>
)
[Learn more about How Agility Page Modules Work in Gatsby](https://help.agilitycms.com/hc/en-us/articles/360043037491)

### How Page Templates Work

Page Templates in Agility CMS are how developers can differentiate the styles of certain types of pages, and define where on the page that editors can add Modules (functional components of the page that editors control). Some sites may only have a single page template and this is re-used across the site, others may have other templates to allow for more flexible layouts.

In the [agilitycms-gatsby-starter](https://github.com/agility/agilitycms-gatsby-starter) site, the Name of the Page Template is used to find a corresponding React component that matches the same name. If a match is found, that component is dynamically imported and rendered.

For example, if a Page Template has a reference name of MainTemplate in the CMS, then while the page is being rendered by the `gatsby-source-agilitycms` plugin, it will look for `src/components/agility-pageTemplates/MainTemplate.jsx` in the `src/components/agility-pageTemplates` directory.

```jsx:title=src/components/agility-pageTemplates/MainTemplate.jsx
import React from "react"
import ContentZone from "../../agility/components/ContentZone"
import { getModule } from "../../components/agility-pageModules"

const MainTemplate = props => {
return (
<div id="main-template">
<ContentZone name="MainContentZone" {...props} getModule={getModule} />
</div>
)
}
export default MainTemplate
```

[Learn more about How Agility Page Templates Work in Gatsby](https://help.agilitycms.com/hc/en-us/articles/360043038271)

### Resolving Linked Content

While you are sourcing and querying content in gatsby, you are likely to come across a scenario where you need to retrieve a content item and its related content. In Agility CMS, Linked Content fields are used to related content to one another in various ways.

When querying a Post, for example, you may want to also retrieve the details for the Category. On your Post GraphQL node, you may notice a category property, however, it will only contain a contentID reference, not the entire node representing the Category. You'll need to resolve this Linked Content when you need it.

In the [agilitycms-gatsby-starter](https://github.com/agility/agilitycms-gatsby-starter), the Linked Content is resolved by using [Gatsby Resolvers](/docs/reference/graphql-data-layer/schema-customization/#createresolvers-api).

Resolvers are added to your `gatsby-node.js` in your site, and they allow you to add a new field to your content node which will handle resolving your Linked Content reference. This means you are telling GraphQL, when you query a specific property on a node, it will actually run a function to go and get your Linked Content and return it.

An example of this can be found [here](https://github.com/agility/agilitycms-gatsby-starter/blob/main/gatsby-node.js) in the starter site:

```js:title=gatsby-node.js
const agility = require("./src/agility/utils")

exports.createResolvers = args => {
const {
createResolvers,
getNode,
createNodeId,
createNode,
createContentDigest,
configOptions,
} = args

// The data needed for Linked Content is resolved here
const resolvers = {
// on the 'agilityPost' node type
agilityPost: {
// get the sitemap node that represents this item ( i.e. /blog/my-blog-post )
sitemapNode: agility.getDynamicPageItemSitemapNode(),

// get the category
linkedContent_agilityCategory: agility.getLinkedContentItem({
type: "agilityCategory",
linkedContentFieldName: "category",
}),
},
}
createResolvers(resolvers)
}
```

Now on the `agilityPost` node, you'll be able to query the category:

```graphql
query {
posts: allAgilityPost {
nodes {
customFields {
title
date(formatString: "MMMM DD, YYYY")
image {
url
label
}
content
}
linkedContent_agilityCategory {
customFields {
title
}
}
}
}
}
```

When you add new modules and content definitions to Agility CMS, the components used to render those modules will automatically receive the strongly typed data delivered to those modules as props.
### How Images Work

Agility CMS also provides `gatsby-image-agilitycms` as a npm package. This is a custom image component that takes images stored within Agility CMS and handles all of the hard parts of displaying responsive images that follow best practices for performance on your website or application.

```jsx
import { AgilityImage } from "@agility/gatsby-image-agilitycms"

const Component = ({ image }) => (
<AgilityImage image={image} layout="fullWidth" />
)
```

[Learn more about How Images Work in Gatsby](https://help.agilitycms.com/hc/en-us/articles/360043048651)

## Resources

- [Agility CMS Official Site](https://agilitycms.com/)
- [Agility CMS & Gatsby Documentation](https://help.agilitycms.com/hc/en-us/articles/360039879872)
- [Agility CMS Community Slack](https://join.slack.com/t/agilitycms-community/shared_invite/zt-99qlv1hw-tpPOJ99V21Y2omtA_uTcJw)