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

Update payload.mdx #2821

Merged
merged 23 commits into from
May 3, 2023
Merged
Changes from 12 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
e569405
Update payload.mdx
isamardzija Mar 9, 2023
9779649
Update src/content/docs/en/guides/cms/payload.mdx
isamardzija Mar 21, 2023
1a89ecb
Update src/content/docs/en/guides/cms/payload.mdx
isamardzija Mar 21, 2023
0bbddaf
Update src/content/docs/en/guides/cms/payload.mdx
isamardzija Mar 21, 2023
b1cecc8
Update src/content/docs/en/guides/cms/payload.mdx
isamardzija Mar 21, 2023
df52df0
Merge branch 'main' into isamardzija-patch-1
isamardzija Apr 5, 2023
7e42381
Merge branch 'main' into isamardzija-patch-1
isamardzija Apr 6, 2023
de78280
Update src/content/docs/en/guides/cms/payload.mdx
isamardzija Apr 6, 2023
891cb29
Update src/content/docs/en/guides/cms/payload.mdx
isamardzija Apr 6, 2023
76e5e5a
fix header link
sarah11918 Apr 7, 2023
8e19a28
Update src/content/docs/en/guides/cms/payload.mdx
isamardzija Apr 14, 2023
1011088
Apply suggestions from code review
sarah11918 May 2, 2023
0d9ef88
remove blank lines
sarah11918 May 2, 2023
0eadcc9
Sarah simplify whether or not used a template
sarah11918 May 2, 2023
84d97ee
Merge branch 'main' into isamardzija-patch-1
sarah11918 May 2, 2023
8ca5203
Update src/content/docs/en/guides/cms/payload.mdx
isamardzija May 3, 2023
dc3a0f7
Update src/content/docs/en/guides/cms/payload.mdx
isamardzija May 3, 2023
6b7ed05
Update src/content/docs/en/guides/cms/payload.mdx
isamardzija May 3, 2023
66603a8
Update src/content/docs/en/guides/cms/payload.mdx
isamardzija May 3, 2023
1679d1b
Update src/content/docs/en/guides/cms/payload.mdx
isamardzija May 3, 2023
a88f207
Update payload.mdx
isamardzija May 3, 2023
8cf1d01
Merge branch 'main' into isamardzija-patch-1
isamardzija May 3, 2023
01d2730
Merge branch 'main' into isamardzija-patch-1
sarah11918 May 3, 2023
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
221 changes: 220 additions & 1 deletion src/content/docs/en/guides/cms/payload.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,226 @@ service: Payload CMS
i18nReady: false
---

[Payload](https://payloadcms.com/) is a headless CMS and application framework.
[PayloadCMS](https://payloadcms.com/) is a headless open-source content management system that can be used to provide content for your Astro project.

## Integrating with Astro

## Prerequisites
ElianCodes marked this conversation as resolved.
Show resolved Hide resolved

To get started, you will need to have the following:
isamardzija marked this conversation as resolved.
Show resolved Hide resolved

1. **An Astro project** - If you don't have an Astro project yet, our [Installation guide](/en/install/auto/) will get you up and running in no time.
2. **A MongoDB database** - PayloadCMS will ask you for a MongoDB connection string when creating a new project. You can set one up locally or use [MongoDBAtlas](https://www.mongodb.com/) to host a database on the web for free.
3. **A PayloadCMS REST API** - Create a [PayloadCMS](https://payloadcms.com/) project and connect it to your MongoDB database during the setup.



sarah11918 marked this conversation as resolved.
Show resolved Hide resolved
:::note[Choosing a template]
During the PayloadCMS installation, you will be asked if you want to use a template.

If you do not choose a template, only a single collection called "Users" will be generated and you will have to [define a PayloadCMS collection manually](#creating-a-payloadcms-collection) in Astro to use for your content.

Choosing any of the available templates at this step (such as 'blog') automatically generates additional collections for you to use. Otherwise, you will need to (manually create your PayloadCMS collections)[].
:::

2. Start the PayloadCMS server using `npm run dev` and visit `http://localhost:3000/admin` to enter your PayloadCMS Dashboard for the first time.
sarah11918 marked this conversation as resolved.
Show resolved Hide resolved

3. Using the Dashboard, create an initial administrator account, which should now be visible as the only entry in your "Users" collection.

#### Creating a PayloadCMS Collection
sarah11918 marked this conversation as resolved.
Show resolved Hide resolved

If you did not choose a template during installation that created a content collection for you, create a new Payload CMS Collection by adding a configuration file in `src/collections/` called `Posts.ts`.

```astro title="src/collections/Posts.ts"
import { CollectionConfig } from "payload/types";

const Posts: CollectionConfig = {
slug: "posts",
admin: {
useAsTitle: "title",
},
access: {
read: () => true,
},

fields: [
{
name: "title",
type: "text",
required: true,
},
{
name: "content",
type: "text",
required: true,
},
{
name: "slug",
type: "text",
required: true,
},
],
};

export default Posts;
```

This creates a "Posts" collection which requires the following : `title`, `content`, `slug`. You will use this collection to manage your blog posts. The colllection is publicly available, so you shouldn't put any sensitive info inside.

You then need to import and add it to the available collections in the `payload.config.ts` file.

```astro title="src/payload.config.ts"
import { buildConfig } from "payload/config";
import path from "path";

import Users from "./collections/Users";
import Posts from "./collections/Posts";

export default buildConfig({
serverURL: "http://localhost:3000",
admin: {
user: Users.slug,
},
collections: [Users, Posts],
typescript: {
outputFile: path.resolve(__dirname, "payload-types.ts"),
},
graphQL: {
schemaOutputFile: path.resolve(__dirname, "generated-schema.graphql"),
},
});
```

If you then go into the PayloadCMS Dashboard, you should see a new collection called "Posts" appear next to the "Users" collection. Enter the "Posts" collection and create a new post. After saving it, you will notice the API URL appear in the bottom right corner.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just pointing out that I'm not sure where the "skippable steps" stop here. If someone chose a template (e.g. blog) would n original post have been created, so this step of creating a new post should also be skipped?

It also seems like the note about both services using port 3000 should not be in the "skipped" section... so I think somewhere here we might need a new subheading so it's more clear where a reader with a template should jump back in to the instructions?

(Note: I did make an earlier suggested edit that took out the instruction to "skip ahead", but then I started the next instruction with "If you didn't choose a template..." So the idea is still the same: we need to make it clear when the "skip/if you choose a template" steps stop so that people are clear about where to jump back in.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent point here, most of these steps can be skipped if the blog template is selected. Personally, I used the UI to create new content

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally, I used the UI to create new content

I think we are talking about the same thing. Do you mean the PayloadCMS Dashboard when you say "UI"?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the confusion, yes I am talking about the Dashboard UI

sarah11918 marked this conversation as resolved.
Show resolved Hide resolved

If not already running, start the server using `npm run dev` again.

Open `http://localhost:3000/api/posts` in your browser. You should see a JSON file containing the post you have created as an object.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
If not already running, start the server using `npm run dev` again.
Open `http://localhost:3000/api/posts` in your browser. You should see a JSON file containing the post you have created as an object.
With the dev server running, open `http://localhost:3000/api/posts` in your browser. You should see a JSON file containing the post you have created as an object.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing that I noticed about the rest endpoint is going to need its own type parser to convert objects to html nodes


:::tip
By default, both Astro and PayloadCMS will use the port 3000. You might want to change the PayloadCMS port in the `src/server.ts` file. Don't forget to update the `serverURL` in `src/payload.config.ts` as well.
:::

```astro title="http://localhost:3000/api/posts"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note to Team Docs:

Have we ever used a website URL as a code snippet title before? I'm not sure what our precedent here is, when you want to tell the reader to navigate to a URL but then what they should see is a code snippet! 😄

What do we think? Do we need anything here?

{
"docs":[
{
"id":"64098b16483b0f06a7e20ed4",
"title":"Astro & PayloadCMS Title 🚀",
"content":"Astro & PayloadCMS Content",
"slug":"astro-payloadcms-slug",
"createdAt":"2023-03-09T07:30:30.837Z",
"updatedAt":"2023-03-09T07:30:30.837Z"
}
],
"totalDocs":1,
"limit":10,
"totalPages":1,
"page":1,
"pagingCounter":1,
"hasPrevPage":false,
"hasNextPage":false,
"prevPage":null,
"nextPage":null
}
```

### Fetching Data

Fetch your PayloadCMS data through your site's unique REST API URL and the route for your content. (By default, PayloadCMS will mount all routes through `/api`.) Then, you can render your data properties using Astro's `set:html=""` directive.
sarah11918 marked this conversation as resolved.
Show resolved Hide resolved

Together with your post, PayloadCMS will return some top-level metadata. The actual documents are nested within the `docs` array.

For example, to display a list of post titles and their content:

```astro title="src/pages/index.astro"
---
import HomeLayout from "../layouts/HomeLayout.astro";

const res = await fetch("https://localhost:5000/api/posts") // https://localhost:3000/api/posts by default
const posts = await res.json()
---

<HomeLayout title='Astro Blog'>
{
posts.docs.map((post) => (
<h2 set:html={post.title} />
<p set:html={post.content} />
))
}
</HomeLayout>
```

## Building a blog with PayloadCMS and Astro

Create a blog index page `src/pages/index.astro` to list each of your posts with a link to its own page.

Fetching via the API returns an array of objects (posts) that include, among others, the following properties:

- `title`
- `content`
- `slug`

```astro title="src/pages/index.astro"
---
import HomeLayout from "../layouts/HomeLayout.astro";

const res = await fetch("http://localhost:5000/api/posts") // https://localhost:3000/api/posts by default
const posts = await res.json()
---

<HomeLayout title='Astro Blog'>
<h1>Astro + PayloadCMS 🚀</h1>
<h2>Blog posts list:</h2>
<ul>
{
posts.docs.map((post) =>(
<li>
<a href={`posts/${post.slug}`} set:html={post.title} />
</li>
))
}

isamardzija marked this conversation as resolved.
Show resolved Hide resolved
</ul>
</HomeLayout>
```

### Using the PayloadCMS API to generate pages

Create a page `src/pages/posts/[slug].astro` to [dynamically generate a page](/en/core-concepts/routing/#dynamic-routes) for each post.

```astro title="src/pages/posts/[slug].astro"
---
import PostLayout from "../../layouts/PostLayout.astro"

const {title, content} = Astro.props

// The getStaticPaths() is required for static Astro sites.
// If using SSR, you will not need this function.
export async function getStaticPaths() {
let data = await fetch("http://localhost:5000/api/posts")
let posts = await data.json()

return posts.docs.map((post) => {
return {
params: {slug: post.slug},
props: {title: post.title, content: post.content},
};
});
}
---
<PostLayout title={title}>
<article>
<h1 set:html={title} />
<p set:html={content} />
</article>
</PostLayout>
```

### Publishing your site

To deploy your site visit our [deployment guide](/en/guides/deploy/) and follow the instructions for your preferred hosting provider.


## Community Resources

Expand Down