skip to content
鰭狀漏斗

Glob Loader 與如何自訂 ID

/ 閱讀時間 3 分鐘

之前我介紹了 Astro 的 Content Layer,有提到有兩個內建的 loader,這次要單獨介紹兩個中其中一個的 glob loader。

glob loader 可以存取本地的 Markdown、MDX、Markdoc 或 JSON 檔案。用法是放在 defineCollection()loader 這個 property 中:

src/content/config.js
import { glob } from 'astro/loaders';
const blog = defineCollection({
loader: glob({ pattern: "**\/*.md", base: "./src/data/blog" }),
schema: /* ... */
});

參數

在上面的例子裡面,glob 接受兩個參數:patternbase

pattern 代表我們想要的檔案路徑的模式,範例中的 "**\/*.md" 表示所有副檔名是 .md 的檔案,不論有沒有在資料夾中都包含。寫法可以 google glob pattern 搜尋教學。原本在 v4 引進的時候,pattern 只能放一個模式,從 v5 開始,我們可以用陣列放多個模式。

base 表示基底的路徑,loader 會從這個路徑以 pattern 的模式搜尋檔案。

雖然範例中沒有,其實 glob 還有第三個參數可以用。你可以用 generateId 自訂 ID 要怎麽生成。

generateId

你可以指定一個函式到 generateId,用這個函式為每一個檔案(entry)產生不同的 ID。glob 暴露了三個變數可以做為函式的參數:entrybasedataentry 是正在處理的 entry 相對於 base 的路徑,base 就是上面傳入的 basedata 則是那個 entry 的資料。

比如說要將 Markdown 檔案的 ID 設為 frontmatter 的 postId property 可以這樣改:

src/content/config.js
import { glob } from 'astro/loaders';
const blog = defineCollection({
loader: glob({ pattern: "**\/*.md", base: "./src/data/blog", generateId: ({ data }) => data.postId }),
schema: /* ... */
});

沒有指定這個函數的時候,預設行為是使用位於同一個檔案的 generateIdDefault 函式。如果有 data.slug 的話就以它做為 ID,否則以相對路徑每層名稱經過 github-slugger 轉換後的結果做為 ID。

如果對使用 Content Layer 的 Content Collection 中每個檔案的 ID 有特別的需求,可以使用 generateId 自訂每個檔案的 ID。

參考資料