Add content collections, layouts and blog pages for Tina integration
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1,4 +1,7 @@
|
|||||||
node_modules
|
node_modules
|
||||||
dist
|
dist
|
||||||
.env
|
.env
|
||||||
*.log
|
*.log
|
||||||
|
.astro
|
||||||
|
package-lock.json
|
||||||
|
.omc
|
||||||
|
|||||||
15
package.json
15
package.json
@@ -1,12 +1,19 @@
|
|||||||
{
|
{
|
||||||
"name": "astro6-simple",
|
"name": "astro-tina",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "astro dev --host 0.0.0.0",
|
"dev": "astro dev --host 0.0.0.0",
|
||||||
"build": "astro build",
|
"build": "astro build",
|
||||||
"preview": "astro preview"
|
"preview": "astro preview",
|
||||||
|
"dev:tina": "tinacms dev -c \"node ./tina/config.server.ts\""
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"astro": "^6.1.7"
|
"astro": "^5.6.1",
|
||||||
|
"@astrojs/mdx": "^4.0.8",
|
||||||
|
"@tinacms/cli": "^2.2.3",
|
||||||
|
"react": "^18.3.1",
|
||||||
|
"react-dom": "^18.3.1",
|
||||||
|
"tinacms": "^2.2.3",
|
||||||
|
"astro-tina": "^0.1.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
22
src/content.config.ts
Normal file
22
src/content.config.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import { defineCollection, z } from "astro:content"
|
||||||
|
|
||||||
|
const postCollection = defineCollection({
|
||||||
|
type: "content",
|
||||||
|
schema: z.object({
|
||||||
|
title: z.string(),
|
||||||
|
description: z.string().optional(),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
|
||||||
|
const pageCollection = defineCollection({
|
||||||
|
type: "content",
|
||||||
|
schema: z.object({
|
||||||
|
title: z.string(),
|
||||||
|
description: z.string().optional(),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
|
||||||
|
export const collections = {
|
||||||
|
posts: postCollection,
|
||||||
|
pages: pageCollection,
|
||||||
|
}
|
||||||
8
src/content/pages/about.md
Normal file
8
src/content/pages/about.md
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
title: About
|
||||||
|
description: About our site
|
||||||
|
---
|
||||||
|
|
||||||
|
# About Us
|
||||||
|
|
||||||
|
We are building modern websites with Astro and Tina CMS.
|
||||||
17
src/content/posts/welcome.md
Normal file
17
src/content/posts/welcome.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
title: Welcome to Astro + Tina
|
||||||
|
description: A modern starter with Astro 6 and Tina CMS
|
||||||
|
---
|
||||||
|
|
||||||
|
# Welcome to Astro + Tina
|
||||||
|
|
||||||
|
This is a sample page managed by Tina CMS.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Visual content editing with Tina CMS
|
||||||
|
- Git-based content management
|
||||||
|
- Static site generation with Astro
|
||||||
|
- Easy deployment on Easypanel
|
||||||
|
|
||||||
|
Stay tuned for more updates!
|
||||||
5
src/content/settings/site.json
Normal file
5
src/content/settings/site.json
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"siteName": "Astro Tina Starter",
|
||||||
|
"siteDescription": "A modern starter template with Astro 6, Tina CMS, and Thai language support.",
|
||||||
|
"language": "th"
|
||||||
|
}
|
||||||
71
src/layouts/Layout.astro
Normal file
71
src/layouts/Layout.astro
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
---
|
||||||
|
const { title, description } = Astro.props
|
||||||
|
---
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="th">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<meta name="description" content={description || "Astro 6 + Tina CMS starter template"} />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||||
|
<title>{title || "Astro Tina Starter"}</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: system-ui, sans-serif;
|
||||||
|
line-height: 1.6;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
background: #f8fafc;
|
||||||
|
color: #0f172a;
|
||||||
|
}
|
||||||
|
main {
|
||||||
|
padding: 4rem 1.5rem;
|
||||||
|
max-width: 64rem;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
font-size: 3rem;
|
||||||
|
font-weight: 700;
|
||||||
|
letter-spacing: -0.025em;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
font-size: 1.125rem;
|
||||||
|
color: #475569;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
max-width: 42rem;
|
||||||
|
}
|
||||||
|
.grid {
|
||||||
|
display: grid;
|
||||||
|
gap: 1.5rem;
|
||||||
|
}
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.grid {
|
||||||
|
grid-template-columns: repeat(2, 1fr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.card {
|
||||||
|
padding: 1.5rem;
|
||||||
|
background: white;
|
||||||
|
border-radius: 0.75rem;
|
||||||
|
border: 1px solid #e2e8f0;
|
||||||
|
}
|
||||||
|
.card h2 {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
.card p {
|
||||||
|
font-size: 1rem;
|
||||||
|
color: #475569;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main data-astro-cid-sckkx6r4>
|
||||||
|
<slot />
|
||||||
|
</main>
|
||||||
|
<script src="https://consent.moreminimore.com/consent-loader.js" data-site-id="demo" data-api-base="https://consent.moreminimore.com"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
57
src/pages/blog.astro
Normal file
57
src/pages/blog.astro
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
---
|
||||||
|
import { getCollection } from 'astro:content'
|
||||||
|
import Layout from "../layouts/Layout.astro"
|
||||||
|
const posts = await getCollection('posts')
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout title="Blog">
|
||||||
|
<main>
|
||||||
|
<h1>Blog Posts</h1>
|
||||||
|
<div class="posts">
|
||||||
|
{posts.map(post => (
|
||||||
|
<article class="post">
|
||||||
|
<h2><a href={`/posts/${post.slug}`}>{post.data.title}</a></h2>
|
||||||
|
{post.data.description && <p>{post.data.description}</p>}
|
||||||
|
</article>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</Layout>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
main {
|
||||||
|
max-width: 64rem;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 4rem 1.5rem;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
}
|
||||||
|
.posts {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 2rem;
|
||||||
|
}
|
||||||
|
.post {
|
||||||
|
padding: 1.5rem;
|
||||||
|
background: white;
|
||||||
|
border-radius: 0.75rem;
|
||||||
|
border: 1px solid #e2e8f0;
|
||||||
|
}
|
||||||
|
.post h2 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
.post h2 a {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.post h2 a:hover {
|
||||||
|
color: #2563eb;
|
||||||
|
}
|
||||||
|
.post p {
|
||||||
|
color: #475569;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
62
src/pages/posts/[slug].astro
Normal file
62
src/pages/posts/[slug].astro
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
---
|
||||||
|
import { getCollection } from 'astro:content'
|
||||||
|
import Layout from "../../layouts/Layout.astro"
|
||||||
|
|
||||||
|
export async function getStaticPaths() {
|
||||||
|
const posts = await getCollection('posts')
|
||||||
|
return posts.map(post => ({
|
||||||
|
params: { slug: post.slug },
|
||||||
|
props: { post },
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
const { post } = Astro.props
|
||||||
|
const { Content } = await post.render()
|
||||||
|
---
|
||||||
|
|
||||||
|
<Layout title={post.data.title} description={post.data.description}>
|
||||||
|
<main>
|
||||||
|
<a href="/blog" class="back">← Back to Blog</a>
|
||||||
|
<article>
|
||||||
|
<h1>{post.data.title}</h1>
|
||||||
|
<Content />
|
||||||
|
</article>
|
||||||
|
</main>
|
||||||
|
</Layout>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
main {
|
||||||
|
max-width: 64rem;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 4rem 1.5rem;
|
||||||
|
}
|
||||||
|
.back {
|
||||||
|
display: inline-block;
|
||||||
|
margin-bottom: 2rem;
|
||||||
|
color: #2563eb;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.back:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
article h1 {
|
||||||
|
font-size: 2.5rem;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
article :global(p) {
|
||||||
|
line-height: 1.8;
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
}
|
||||||
|
article :global(h2) {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
margin-top: 2rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
article :global(ul) {
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
padding-left: 1.5rem;
|
||||||
|
}
|
||||||
|
article :global(li) {
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user