feat: add categories and tags page (WIP)

This commit is contained in:
grassblock 2025-05-28 22:19:01 +08:00
parent 1e7f0f9e4a
commit 00115ad5a0
6 changed files with 104 additions and 0 deletions

View file

@ -5,6 +5,8 @@ export const posts = ({ image }) => z.object({
description: z.string(), description: z.string(),
pubDate: z.coerce.date(), pubDate: z.coerce.date(),
updatedDate: z.coerce.date().optional(), updatedDate: z.coerce.date().optional(),
categories: z.array(z.string()).optional().default(['uncategorized']),
tags: z.array(z.string()).optional().default([]),
cover: image().optional(), cover: image().optional(),
author: z.string().optional(), author: z.string().optional(),
}); });

View file

@ -3,6 +3,10 @@ title: 'The Art of Minimalism'
description: 'Thoughts on minimalism in design and code' description: 'Thoughts on minimalism in design and code'
pubDate: '2025-06-05' pubDate: '2025-06-05'
author: 'Wheatley' author: 'Wheatley'
tags:
- 'design'
- 'code'
- 'minimalism'
--- ---
Minimalism isn't just about having less, it's about making room for what matters. Minimalism isn't just about having less, it's about making room for what matters.

View file

@ -0,0 +1,17 @@
---
import {getCollection} from "astro:content";
import Layout from "../layouts/Layout.astro";
const allPosts = await getCollection('posts');
const uniqueCategories = [...new Set(allPosts.map((post: any) => post.data.categories ? post.data.categories : []).flat())];
---
<Layout title="Categoies" description="List all categories used in the blog posts.">
<h1 class="title">~/blog/categories</h1>
<div style="margin-top: 2rem;">
<span class="command">ls -l categories/</span>
<div style="margin-top: 1rem; margin-left: 1rem;">
{uniqueCategories.map((tag) => (
<p><a href={`/categories/${tag}`}>{tag}</a></p>
))}
</div>
</div>
</Layout>

View file

@ -0,0 +1,33 @@
---
import Layout from '../../layouts/Layout.astro';
import {getCollection} from "astro:content";
import {categoryLabel} from "astro/client/dev-toolbar/apps/audit/rules";
export async function getStaticPaths() {
const allPosts = await getCollection('posts');
console.log(allPosts)
const uniqueCategories = [...new Set(allPosts.map((post: any) => post.data.categories ? post.data.categories : []).flat())];
return uniqueCategories.map((category) => {
const filteredPosts = allPosts.filter((post: any) => post.data.categories?.includes(category));
return {
params: { category },
props: { posts: filteredPosts },
};
});
}
const { category } = Astro.params;
const { posts } = Astro.props;
---
<Layout title={`posts tagged with ${category}`} description={`Posts tagged with ${category}`}>
<h1 class="title">ls ~/blog | grep "{category}"</h1>
<ul>
{posts.map((post: any) =>
<p>
<span class="list-date">{new Date(post.data.pubDate).toISOString().split('T')[0]}</span>
<a href={`/post/${post.slug}`}>{post.data.title}</a>
</p>
)}
</ul>
</Layout>

17
src/pages/tags.astro Normal file
View file

@ -0,0 +1,17 @@
---
import {getCollection} from "astro:content";
import Layout from "../layouts/Layout.astro";
const allPosts = await getCollection('posts');
const uniqueTags = [...new Set(allPosts.map((post: any) => post.data.tags ? post.data.tags : []).flat())];
---
<Layout title="Tags" description="List all tags used in the blog posts.">
<h1 class="title">~/blog/tags</h1>
<div style="margin-top: 2rem;">
<span class="command">ls -l tags/</span>
<div style="margin-top: 1rem; margin-left: 1rem;">
{uniqueTags.map((tag) => (
<p><a href={`/tags/${tag}`}>{tag}</a></p>
))}
</div>
</div>
</Layout>

View file

@ -0,0 +1,31 @@
---
import Layout from '../../layouts/Layout.astro';
import {getCollection} from "astro:content";
export async function getStaticPaths() {
const allPosts = await getCollection('posts');
const uniqueTags = [...new Set(allPosts.map((post: any) => post.data.tags ? post.data.tags : []).flat())];
return uniqueTags.map((tag) => {
const filteredPosts = allPosts.filter((post: any) => post.data.tags?.includes(tag));
return {
params: { tag },
props: { posts: filteredPosts },
};
});
}
const { tag } = Astro.params;
const { posts } = Astro.props;
---
<Layout title={`posts tagged with ${tag}`} description={`Posts tagged with ${tag}`}>
<h1 class="title">ls ~/blog | grep "{tag}"</h1>
<ul>
{posts.map((post: any) =>
<p>
<span class="list-date">{new Date(post.data.pubDate).toISOString().split('T')[0]}</span>
<a href={`/post/${post.slug}`}>{post.data.title}</a>
</p>
)}
</ul>
</Layout>