add dynamic tag pages to display blog posts by tags
This commit is contained in:
parent
0511d90911
commit
05dfaed605
2 changed files with 78 additions and 14 deletions
|
|
@ -1,24 +1,29 @@
|
|||
---
|
||||
import { getCollection } from "astro:content";
|
||||
import { getCollection, render, type CollectionEntry, type RenderResult } from "astro:content";
|
||||
import Layout from "../../layouts/Layout.astro";
|
||||
import BlogPost from "../../components/BlogPost.astro";
|
||||
import { render } from "astro:content";
|
||||
import type { CollectionEntry } from "astro:content";
|
||||
|
||||
interface Props {
|
||||
post: CollectionEntry<"blog">;
|
||||
}
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const posts = await getCollection("blog");
|
||||
return posts.map((post) => ({
|
||||
params: { slug: post.id },
|
||||
props: { post },
|
||||
}));
|
||||
const paths = await Promise.all(
|
||||
posts.map(async (post) => {
|
||||
const id = post.id;
|
||||
const content = await render(post);
|
||||
return {
|
||||
params: { id },
|
||||
props: { post, content },
|
||||
};
|
||||
})
|
||||
);
|
||||
return paths;
|
||||
}
|
||||
|
||||
const { post } = Astro.props;
|
||||
const renderedPost = await render(post);
|
||||
interface Props {
|
||||
post: CollectionEntry<"blog">;
|
||||
content: RenderResult;
|
||||
}
|
||||
|
||||
const { post, content } = Astro.props;
|
||||
---
|
||||
|
||||
<Layout
|
||||
|
|
@ -31,6 +36,6 @@ const renderedPost = await render(post);
|
|||
date={post.data.date}
|
||||
tags={post.data.tags}
|
||||
>
|
||||
<renderedPost.Content />
|
||||
<content.Content />
|
||||
</BlogPost>
|
||||
</Layout>
|
||||
59
src/pages/tags/[name].astro
Normal file
59
src/pages/tags/[name].astro
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
---
|
||||
import { getCollection, type CollectionEntry } from "astro:content";
|
||||
import BlogPostCard from "../../components/BlogPostCard.astro";
|
||||
import Layout from "../../layouts/Layout.astro";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const posts = await getCollection("blog");
|
||||
const tags = new Set<string>();
|
||||
|
||||
posts.forEach((post) => {
|
||||
if (post.data.tags) {
|
||||
post.data.tags.forEach((tag: string) => tags.add(tag));
|
||||
}
|
||||
});
|
||||
|
||||
return Array.from(tags).map((name) => {
|
||||
const filteredPosts = posts.filter(
|
||||
(post) => post.data.tags && post.data.tags.includes(name),
|
||||
);
|
||||
return {
|
||||
params: { name },
|
||||
props: { filteredPosts },
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
interface Props {
|
||||
filteredPosts: CollectionEntry<"blog">[];
|
||||
}
|
||||
|
||||
const { name } = Astro.params;
|
||||
const { filteredPosts } = Astro.props;
|
||||
---
|
||||
|
||||
<Layout
|
||||
title={`Posts tagged with "${name}" - Dhemas Nurjaya`}
|
||||
description={`Browse blog posts tagged with "${name}" by Dhemas Nurjaya`}
|
||||
>
|
||||
<h1 class="text-4xl font-bold mb-8">Posts tagged with "{name}"</h1>
|
||||
{
|
||||
filteredPosts.length > 0 ? (
|
||||
<ul class="space-y-4">
|
||||
{filteredPosts.map((post) => (
|
||||
<li>
|
||||
<BlogPostCard
|
||||
id={post.id}
|
||||
title={post.data.title}
|
||||
date={post.data.date}
|
||||
description={post.data.description}
|
||||
tags={post.data.tags}
|
||||
/>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
) : (
|
||||
<p class="text-lg text-zinc-400">No posts found with the tag "{name}".</p>
|
||||
)
|
||||
}
|
||||
</Layout>
|
||||
Loading…
Add table
Add a link
Reference in a new issue