捨棄 create-react-app 之餘還架了個 astro blog 昭告天下:靜態路由與 /archive
普通讀者 2.0 全文章歸檔頁的設計非常陽春單純。目前仗著文章還未爆量,在把文章根據年份分類後就全部灑到畫面上。而又因為我們在第 20 天就處理好「排序後的全文章陣列」,今天只要再加上一點點工就能做出 /archive 頁。來看看吧。
本文
groupPostByYear
首先打開老朋友 ./src/tools/post.ts
並追加功能 groupPostByYear
。
export function groupPostByYear(posts: MarkdownInstance<Post>[]) {
const yearsMap: Record<string, MarkdownInstance<Post>[]> = {};
posts.forEach((post) => {
const y = dayjs(post.frontmatter.date).format('YYYY');
if (!yearsMap[y]) {
yearsMap[y] = [];
}
yearsMap[y].push(post);
});
return yearsMap;
}
我們在這裡做的事情是:
- 將傳入的
posts
參數根據每一篇文章的frontmatter.date
資訊進行分類 - 遍歷整個
posts
陣列,並且在最終要回傳的結果yearsMap
還沒有對應的年份時,為該年份新增一個空陣列 - 將屬於年份 x 的文章歸類到
yearsMap[年份 x]
中
最後拿到的物件結構如下圖。部落格文章有多少年份,物件的鍵就會有那些對應的年份出現:
const groupByYearPosts = {
2023: [...],
2022: [...],
2021: [...]
}
/archive 頁
參考官方文件可得知:在資料夾 ./src/pages
中的 .astro
與 .md
/ .mdx
都會被自動解析成網頁。且 url 轉換規則如下:
src/pages/index.astro -> ${site_domain}.com/
src/pages/about.astro -> ${site_domain}.com/about
src/pages/about/index.astro -> ${site_domain}.com/about
src/pages/about/me.astro -> ${site_domain}.com/about/me
src/pages/posts/1.md -> ${site_domain}.com/posts/1
所以 src/pages/archive/index.astro
這個元件就是使用者移動到部落格 /archive
路由時會看到的內容。
在 Component Script 部位做的事情很單純:
- 將
ALL_SORTED_POSTS
透過groupPostByYear
讓文章們根據年份分類,取得groupByYearPosts
- 取出純年份資料
sortYears
並透過.sort()
確保年份從大(新)排序到小(舊)
資料整理好之後,就可以在 Component Template 區塊渲染了。
<Html>
{
sortYears.map((year, i) => (
<>
<div class="year-container">
<h2>
{year}(計{groupByYearPosts[year].length}篇)
</h2>
<ul class="post-container">
{groupByYearPosts[year].map((post) => (
<PostItem post={post} />
))}
</ul>
</div>
{i !== sortYears.length - 1 && <hr class="divider" />}
</>
))
}
</Html>
除了年份以及文章列表以外,每一輪遞迴最下方都會根據「是否已經到達最後一年(i !== sortYears.length - 1
)」來決定是否於畫面上追加 <hr />
元件。
一個 /archive 就這樣完工了 (≖ᴗ≖๑)
總結
在 static route 的情況下,於 astro 新增一個畫面就是如此簡單。
別擔心,明天就會透過普通讀者 2.0 的標籤頁來介紹如何處理 dynamic route (●⁰౪⁰●)