feat: enhance blog structure with categories, tags, and localization updates

This commit is contained in:
Thuan Bui
2026-03-14 15:24:59 +07:00
parent ea37a4ece7
commit 6342b8a3aa
11 changed files with 66 additions and 41 deletions
+81
View File
@@ -0,0 +1,81 @@
---
import BaseLayout from "@/layouts/BaseLayout.astro";
import Schema from "@/components/seo/Schema.astro";
import { getCollection, render } from "astro:content";
export async function getStaticPaths() {
const blog = await getCollection("blog");
return blog.map((post) => ({
params: { slug: post.id },
props: { post },
}));
}
const { post } = Astro.props;
const { Content, remarkPluginFrontmatter } = await render(post);
const { title, description, pubDate, author, image } = post.data;
const formattedDate = pubDate.toLocaleDateString("vi-VN", {
year: "numeric",
month: "long",
day: "numeric",
});
const readingTime = remarkPluginFrontmatter?.minutesRead
? `${Math.ceil(remarkPluginFrontmatter.minutesRead)} phút đọc`
: "";
const metadata = {
title: title,
description: description,
ogImage: image,
};
---
<BaseLayout metadata={metadata}>
<Schema
type="BlogPosting"
data={{
title,
description,
image,
pubDate,
author,
url: Astro.url.href,
}}
/>
<section class="relative px-4 py-8 sm:px-6 lg:px-8 md:py-12">
<div class="relative mx-auto max-w-3xl">
<div class="reveal mb-10 text-center">
<p class="text-sm font-semibold tracking-wide text-primary uppercase">
{formattedDate} • {author}
{readingTime && ` • ${readingTime}`}
</p>
<h1
class="font-heading mt-2 text-3xl font-bold leading-tight tracking-tighter text-foreground sm:text-4xl md:text-5xl"
>
{title}
</h1>
</div>
{
image && (
<div class="reveal relative mb-8 h-96 w-full overflow-hidden rounded-xl shadow-lg">
<img
src={`/images/${image}`}
alt={title}
class="h-full w-full object-cover"
/>
</div>
)
}
<div
class="reveal prose prose-lg dark:prose-invert mx-auto prose-headings:text-foreground prose-a:text-primary hover:prose-a:underline prose-p:text-muted-foreground prose-strong:text-foreground prose-li:text-muted-foreground prose-code:text-primary"
>
<Content />
</div>
</div>
</section>
</BaseLayout>