Astro Content Collections: จัดการ Markdown และ MDX อย่างมีระบบ
#astro12 เม.ย. 2569
Content Collections คืออะไร
Content Collections เป็น API ของ Astro สำหรับจัดการ content ที่เป็น Markdown, MDX หรือ JSON โดยมี type safety และ validation
โครงสร้าง
src/
content/
config.ts # กำหนด schema
blog/
post-1.md
post-2.mdx
docs/
intro.md
กำหนด Schema
// src/content/config.ts
import { defineCollection, z } from 'astro:content';
const blog = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
description: z.string(),
pubDate: z.date(),
author: z.string().default('ทีมงาน'),
tags: z.array(z.string()).default([]),
image: z.object({
url: z.string(),
alt: z.string()
}).optional(),
draft: z.boolean().default(false)
})
});
export const collections = { blog };
สร้าง Markdown Post
---
title: "บทความแรก"
description: "บทความแรกของฉัน"
pubDate: 2024-01-15
author: "สมชาย"
tags: ["astro", "web"]
---
# บทความแรก
เนื้อหาบทความ...
Query Content
---
import { getCollection, getEntry } from 'astro:content';
// ดึงทุก post
const posts = await getCollection('blog');
// กรอง draft
const publishedPosts = await getCollection('blog', ({ data }) => {
return !data.draft;
});
// เรียงตามวันที่
const sortedPosts = posts.sort(
(a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf()
);
// ดึง post เดียว
const post = await getEntry('blog', 'post-1');
---
<ul>
{sortedPosts.map(post => (
<li>
<a href={`/blog/${post.slug}`}>{post.data.title}</a>
</li>
))}
</ul>
Dynamic Routes
---
// src/pages/blog/[slug].astro
import { getCollection } from 'astro:content';
export async function getStaticPaths() {
const posts = await getCollection('blog');
return posts.map(post => ({
params: { slug: post.slug },
props: { post }
}));
}
const { post } = Astro.props;
const { Content } = await post.render();
---
<article>
<h1>{post.data.title}</h1>
<Content />
</article>
สรุป
Content Collections ทำให้จัดการ content ได้อย่างมีระบบ มี type safety และ validation ช่วยป้องกัน error ตั้งแต่ development time ครับ