分類法是用於組織內容的分類系統。EmDash 包含內建的分類和標籤,並支援自訂分類法以滿足專業化的分類需求。
內建分類法
EmDash 提供兩種預設分類法:
| 分類法 | 類型 | 描述 |
|---|---|---|
| 分類 | 階層型 | 具有父子關係的巢狀分類 |
| 標籤 | 扁平型 | 無階層的簡單標籤 |
兩者預設可用於文章集合。
管理術語
建立術語
管理面板
-
前往分類法頁面(例如
/_emdash/admin/taxonomies/category) -
在新增表單中輸入術語名稱
-
可選設定:
- Slug - URL 識別碼(從名稱自動產生)
- 父級 - 用於階層型分類法
- 描述 - 術語描述
-
點擊新增
內容編輯器
-
在編輯器中開啟一個內容條目
-
在側邊欄找到分類法面板
-
對於分類,勾選適用術語的核取方塊,或點擊 + 新增
-
對於標籤,輸入用逗號分隔的標籤名稱
-
儲存內容
API
以下請求在 category 分類法中建立一個術語:
POST /_emdash/api/taxonomies/category/terms
Content-Type: application/json
Authorization: Bearer YOUR_API_TOKEN
{
"slug": "tutorials",
"label": "教學",
"parentId": "term_abc",
"description": "操作指南和教學"
} 編輯術語
-
前往分類法術語頁面
-
點擊術語旁邊的編輯
-
更新名稱、slug、父級或描述
-
點擊儲存
刪除術語
-
前往分類法術語頁面
-
點擊術語旁邊的刪除
-
確認刪除
查詢分類法
EmDash 提供用於查詢分類法術語和按術語篩選內容的函式。
取得所有術語
擷取分類法的所有術語:
import { getTaxonomyTerms } from "emdash";
// 取得所有分類(回傳樹狀結構)
const categories = await getTaxonomyTerms("category");
// 取得所有標籤(回傳扁平列表)
const tags = await getTaxonomyTerms("tag");
對於階層型分類法,術語包含 children 陣列:
interface TaxonomyTerm {
id: string;
name: string; // 分類法名稱 ("category")
slug: string; // 術語 slug ("news")
label: string; // 顯示標籤 ("News")
parentId?: string;
description?: string;
children: TaxonomyTerm[];
count?: number; // 使用此術語的條目數
}
計算 count 會聚合分類法集合中的每個內容-術語分配,這是呼叫中最昂貴的部分。如果你只需要標籤和 slug,可以略過——count 將從回傳的術語中省略:
const tags = await getTaxonomyTerms("tag", { includeCounts: false });
取得單一術語
以下範例按分類法和 slug 取得術語:
import { getTerm } from "emdash";
const category = await getTerm("category", "news");
// 回傳 TaxonomyTerm 或 null
取得條目的術語
以下範例擷取分配給單一條目的分類和標籤:
import { getEntryTerms } from "emdash";
// 取得文章的所有分類
const categories = await getEntryTerms("posts", "post-123", "category");
// 取得文章的所有標籤
const tags = await getEntryTerms("posts", "post-123", "tag");
按術語篩選內容
使用 getEmDashCollection 搭配 where 篩選器:
import { getEmDashCollection } from "emdash";
// "news" 分類的文章
const { entries: newsPosts } = await getEmDashCollection("posts", {
status: "published",
where: { category: "news" },
});
// "javascript" 標籤的文章
const { entries: jsPosts } = await getEmDashCollection("posts", {
status: "published",
where: { tag: "javascript" },
});
或使用便捷函式:
import { getEntriesByTerm } from "emdash";
const newsPosts = await getEntriesByTerm("posts", "category", "news");
建構分類法頁面
分類封存
建立一個列出某分類文章的頁面:
---
import { getTaxonomyTerms, getTerm, getEmDashCollection } from "emdash";
import Base from "../../layouts/Base.astro";
export async function getStaticPaths() {
const categories = await getTaxonomyTerms("category");
function flatten(terms) {
return terms.flatMap((term) => [term, ...flatten(term.children)]);
}
return flatten(categories).map((cat) => ({
params: { slug: cat.slug },
props: { category: cat },
}));
}
const { category } = Astro.props;
const { entries: posts } = await getEmDashCollection("posts", {
status: "published",
where: { category: category.slug },
});
---
<Base title={category.label}>
<h1>{category.label}</h1>
{category.description && <p>{category.description}</p>}
<p>{category.count} 篇文章</p>
<ul>
{posts.map((post) => (
<li>
<a href={`/blog/${post.data.slug}`}>{post.data.title}</a>
</li>
))}
</ul>
</Base>
標籤封存
建立一個列出某標籤文章的頁面:
---
import { getTaxonomyTerms, getEmDashCollection } from "emdash";
import Base from "../../layouts/Base.astro";
export async function getStaticPaths() {
const tags = await getTaxonomyTerms("tag");
return tags.map((tag) => ({
params: { slug: tag.slug },
props: { tag },
}));
}
const { tag } = Astro.props;
const { entries: posts } = await getEmDashCollection("posts", {
status: "published",
where: { tag: tag.slug },
});
---
<Base title={`標籤「${tag.label}」的文章`}>
<h1>#{tag.label}</h1>
<ul>
{posts.map((post) => (
<li>
<a href={`/blog/${post.data.slug}`}>{post.data.title}</a>
</li>
))}
</ul>
</Base>
分類列表元件
顯示帶有文章計數的分類列表:
---
import { getTaxonomyTerms } from "emdash";
const categories = await getTaxonomyTerms("category");
---
<nav class="category-list">
<h3>分類</h3>
<ul>
{categories.map((cat) => (
<li>
<a href={`/category/${cat.slug}`}>
{cat.label} ({cat.count})
</a>
{cat.children.length > 0 && (
<ul>
{cat.children.map((child) => (
<li>
<a href={`/category/${child.slug}`}>
{child.label} ({child.count})
</a>
</li>
))}
</ul>
)}
</li>
))}
</ul>
</nav>
標籤雲
根據使用頻率顯示不同大小的標籤:
---
import { getTaxonomyTerms } from "emdash";
const tags = await getTaxonomyTerms("tag");
const counts = tags.map((t) => t.count ?? 0);
const maxCount = Math.max(...counts, 1);
const minSize = 0.8;
const maxSize = 2;
function getSize(count: number) {
const ratio = count / maxCount;
return minSize + ratio * (maxSize - minSize);
}
---
<div class="tag-cloud">
{tags.map((tag) => (
<a
href={`/tag/${tag.slug}`}
style={`font-size: ${getSize(tag.count ?? 0)}rem`}
>
{tag.label}
</a>
))}
</div>
在內容上顯示術語
在文章上顯示分類和標籤:
---
import { getEntryTerms } from "emdash";
interface Props {
collection: string;
entryId: string;
}
const { collection, entryId } = Astro.props;
const categories = await getEntryTerms(collection, entryId, "category");
const tags = await getEntryTerms(collection, entryId, "tag");
---
<div class="post-terms">
{categories.length > 0 && (
<div class="categories">
<span>發佈於:</span>
{categories.map((cat, i) => (
<>
{i > 0 && ", "}
<a href={`/category/${cat.slug}`}>{cat.label}</a>
</>
))}
</div>
)}
{tags.length > 0 && (
<div class="tags">
{tags.map((tag) => (
<a href={`/tag/${tag.slug}`} class="tag">
#{tag.label}
</a>
))}
</div>
)}
</div>
自訂分類法
為專業化需求建立超越分類和標籤的分類法。
建立自訂分類法
使用管理 API 建立分類法:
POST /_emdash/api/taxonomies
Content-Type: application/json
Authorization: Bearer YOUR_API_TOKEN
{
"name": "genre",
"label": "類型",
"labelSingular": "類型",
"hierarchical": true,
"collections": ["books", "movies"]
}
使用自訂分類法
以與內建分類法相同的方式查詢和顯示自訂分類法:
import { getTaxonomyTerms, getEmDashCollection } from "emdash";
// 取得所有類型
const genres = await getTaxonomyTerms("genre");
// 取得某類型的書籍
const { entries: sciFiBooks } = await getEmDashCollection("books", {
where: { genre: "science-fiction" },
});
分配到集合
分類法指定它們適用於哪些集合:
{
"name": "difficulty",
"label": "難度級別",
"hierarchical": false,
"collections": ["recipes", "tutorials"]
}
分類法 API 參考
REST 端點
| 端點 | 方法 | 描述 |
|---|---|---|
/_emdash/api/taxonomies | GET | 列出分類法定義 |
/_emdash/api/taxonomies | POST | 建立分類法 |
/_emdash/api/taxonomies/:name/terms | GET | 列出術語 |
/_emdash/api/taxonomies/:name/terms | POST | 建立術語 |
/_emdash/api/taxonomies/:name/terms/:slug | GET | 取得術語 |
/_emdash/api/taxonomies/:name/terms/:slug | PUT | 更新術語 |
/_emdash/api/taxonomies/:name/terms/:slug | DELETE | 刪除術語 |
為內容分配術語
以下請求為文章分配分類術語:
POST /_emdash/api/content/posts/post-123/terms/category
Content-Type: application/json
Authorization: Bearer YOUR_API_TOKEN
{
"termIds": ["term_news", "term_featured"]
}