捨棄 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;
}

我們在這裡做的事情是:

  1. 將傳入的 posts 參數根據每一篇文章的 frontmatter.date 資訊進行分類
  2. 遍歷整個 posts 陣列,並且在最終要回傳的結果 yearsMap 還沒有對應的年份時,為該年份新增一個空陣列
  3. 將屬於年份 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 部位做的事情很單純:

  1. ALL_SORTED_POSTS 透過 groupPostByYear 讓文章們根據年份分類,取得 groupByYearPosts
  2. 取出純年份資料 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 (●⁰౪⁰●)