在前幾天,我們已經學會了如何建立文章列表,今天將介紹如何在 Astro 裡實現文章標籤與標籤列表頁面。文章標籤是不可或缺的,它有助於組織和分類文章,讓讀者更輕鬆地尋找相關內容!
在開始之前,確保你的文章資訊中包含了標籤(tags)
的資訊。這些標籤將用於分類文章。請檢查 src/content/blog
裡的 markdown
檔案,確保每篇文章中都有 tags 的資訊。
如下圖:
同時,打開 src/content/config.ts
並確保已配置了標籤相關的設定。
在 src/components
資料夾中建立一個名為 Tags.astro
的組件,這個組件將用於顯示文章的標籤。
我們一樣在 tailwind components 找一個喜歡的樣式套上
---
const { tags } = Astro.props;
---
{
(tags || []).map((tag: any) => {
return (
<a href={`/blog/tags/${tag.toLowerCase()}`} class="mr-4 inline-block relative py-1 text-xs">
<div class="absolute inset-0 text-neutral-200 flex">
<svg viewBox="0 0 50 100">
<path
d="M49.9,0a17.1,17.1,0,0,0-12,5L5,37.9A17,17,0,0,0,5,62L37.9,94.9a17.1,17.1,0,0,0,12,5ZM25.4,59.4a9.5,9.5,0,1,1,9.5-9.5A9.5,9.5,0,0,1,25.4,59.4Z"
fill="currentColor"
/>
</svg>
<div class="flex-grow h-full -ml-px bg-neutral-200 rounded-md rounded-l-none" />
</div>
<span class="relative text-neutral-500 uppercase font-semibold pr-px">
<span> </span>{tag}<span> </span>
</span>
</a>
);
})
}
接著在昨天寫好的 src/page/[page].astro
裡引用 Tags.astro
組件
---
// ...其他 import 省略
import Tags from '../../../components/Tags.astro';
// ...其他程式碼省略
---
<MainLayout title={SITE_TITLE} description={SITE_DESCRIPTION}>
<main>
<section>
<ul>
{
data.map((post) => (
<p>
<FormattedDate date={post.data.pubDate} />{' '}
<a href={`/blog/${post.slug}/`}>{post.data.title}</a>
<Tags tags={post.data.tags} /> {/* 新增 Tags 組件 */}
</p>
))
}
</ul>
</section>
<!-- ...略 -->
</main>
</MainLayout>
../../../components/Tags.astro
引入 Tags 組件。<Tags tags={post.data.tags} />
將文章的標籤傳遞給 Tags
組件,這樣每篇文章都會顯示相關的標籤。最後,再建立標籤列表頁面,以便讀者可以瀏覽特定標籤下的文章。
在 src/pages/blog
建立一個 tags
資料夾,再新增 [tag].astro
檔案
---
import { getCollection } from 'astro:content';
import { sortByDate } from '../../../lib/sortByDate';
import MainLayout from '../../../layouts/MainLayout.astro';
import FormattedDate from '../../../components/FormattedDate.astro';
export async function getStaticPaths() {
const posts = await getCollection('blog');
// 取得所有不重複的標籤
const tags = [
...new Set(posts.map((post: any) => post.data.tags).flat()),
].filter((d: any) => !!d);
// 建立每個標籤的路徑
const tagsList = tags.map((t: any) => {
return {
params: { tags: t.toLowerCase() },
props: {
tag: t,
posts: sortByDate(
posts.filter((p) => {
return p.data.tags
?.map((tag: any) => tag.toLowerCase())
.includes(t.toLowerCase());
})
),
},
};
});
return tagsList
}
const { posts, tag } = Astro.props as any;
---
<MainLayout title={tag} >
<main>
<ul>
{
posts.map((post:any) => {
return (
<li>
<a href={`/blog/${post.slug}`}>
<FormattedDate
date={post.data.pubDate}
/>
<span class="ml-4">{post.data.title}</span>
</a>
</li>
)
})
}
</ul>
</main>
</MainLayout>
今天,我們學到了:
(Tags)
的方法,以提供更豐富的內容呈現。範例連結:https://stackblitz.com/edit/withastro-astro-ftzl1y