Skip to content
This repository has been archived by the owner on Dec 19, 2024. It is now read-only.

feat: Static cms custom views for people and news #82

Merged
merged 6 commits into from
Aug 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ module.exports = {
"out",
"build",
"node_modules",
"public/admin/previews"
],
plugins: ["@typescript-eslint", "import"],
rules: {
Expand Down
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Mesoamerican Migration Project
├── public/
├── admin/
├──config.yml
├── previews/

├── src/
│ ├── components/
Expand All @@ -20,6 +21,25 @@ Mesoamerican Migration Project
└── tsconfig.json
```

## StaticCMS

Link to docs: https://www.staticcms.org/docs/

### Collections

The collections for the CMS are defined in the public/admin/config.yml file. Here is where you can add/remove/edit any
specific fields within a collection, specify output paths for collections, and configure i18n.

If you edit any fields, make sure they match in astro's content configuration, located in the src/content/config.ts
file. We use zod to type the markdown file frontmatter.

### Previews

StaticCMS enables custom previews by exposing a few constructs globally to allow us to create components inline. While
the docs show examples for tsx and jsx, only js files with the h function seem to work at this time.

When editing styling for the People page or the News page, be sure to edit the corresponding preview pages to match.

## Getting Started with Development

### Install Dependencies
Expand Down
20 changes: 14 additions & 6 deletions public/admin/index.html
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="https://unpkg.com/@staticcms/app@^4.0.0/dist/main.css" />
<title>Content Manager</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="https://unpkg.com/@staticcms/app@^4.0.0/dist/main.css" />
<title>Content Manager</title>
</head>
<body>
<!-- Include the script that builds the page and powers Static CMS -->
<script src="https://unpkg.com/@staticcms/app@^4.0.0/dist/static-cms-app.js"></script>
<script>
window.CMS.init();
<script type="module">
import { PeoplePreview } from "./previews/PeoplePreview.js"
import { NewsPreview } from "./previews/NewsPreview.js"

window.CMS.init()
window.CMS.registerPreviewStyle("../src/styles/global.css")

window.CMS.registerPreviewTemplate("people", PeoplePreview)
window.CMS.registerPreviewTemplate("news", NewsPreview)

</script>
</body>
</html>
23 changes: 23 additions & 0 deletions public/admin/previews/NewsPreview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export const NewsPreview = ({ widgetFor, entry, collection, fields }) => {
const imageField = useMemo(() => fields.find((field) => field.name === "heroImage"), [fields])
const imageUrl = useMediaAsset(entry.data.heroImage, collection, imageField, entry)

return h(
"div",
{},
h("div", { className: "space-y-3 pb-6" }, h("h1", {}, entry.data.title)),
h("hr", { className: "border-none h-0.5 bg-neutral-900 mb-16" }),
h(
"div",
{},
h(
"div",
{},

h("img", { src: imageUrl, className: "w-full" })
),
h("time", {}, entry.data.pubDate),
h("div", { className: "text" }, widgetFor("body"))
)
)
}
29 changes: 29 additions & 0 deletions public/admin/previews/PeoplePreview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
export const PeoplePreview = ({ entry, collection, fields }) => {
const imageField = useMemo(() => fields.find((field) => field.name === "avatar"), [fields])
const imageUrl = useMediaAsset(entry.data.avatar, collection, imageField, entry)

return h(
"div",
{ className: "flex flex-col mt-4 md:flex-row gap-4 md:gap-8" },
h(
"div",
{ className: "flex-none" },

h("img", { src: imageUrl, className: "object-cover rounded-full w-40 h-40 md:w-64 md:h-64" })
),
h(
"div",
{ className: "space-y-4" },
h(
"div",
{},

h("p", { className: "text-xl font-semibold underline text-neutral-900" }, entry.data.name),
h("p", { className: "text-neutral-700 italic" }, entry.data.title),
h("p", { className: "small" }, entry.data.org)
),

h("p", {}, entry.data.bio)
)
)
}