feat: add categories and tags page (WIP)
This commit is contained in:
parent
1e7f0f9e4a
commit
00115ad5a0
6 changed files with 104 additions and 0 deletions
|
@ -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(),
|
||||||
});
|
});
|
|
@ -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.
|
||||||
|
|
17
src/pages/categories.astro
Normal file
17
src/pages/categories.astro
Normal 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>
|
33
src/pages/categories/[...category].astro
Normal file
33
src/pages/categories/[...category].astro
Normal 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
17
src/pages/tags.astro
Normal 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>
|
31
src/pages/tags/[...tag].astro
Normal file
31
src/pages/tags/[...tag].astro
Normal 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>
|
Loading…
Add table
Add a link
Reference in a new issue