분류 체계는 콘텐츠를 정리하기 위한 분류 시스템입니다. EmDash에는 내장 카테고리와 태그가 포함되어 있으며, 전문적인 분류 요구에 맞는 사용자 정의 분류 체계를 지원합니다.
내장 분류 체계
EmDash는 두 가지 기본 분류 체계를 제공합니다:
| 분류 체계 | 유형 | 설명 |
|---|---|---|
| 카테고리 | 계층형 | 부모-자식 관계를 가진 중첩 분류 |
| 태그 | 플랫 | 계층 없는 단순 라벨 |
둘 다 기본적으로 게시물 컬렉션에서 사용 가능합니다.
용어 관리
용어 생성
관리자 대시보드
-
분류 체계 페이지로 이동합니다 (예:
/_emdash/admin/taxonomies/category) -
새로 추가 폼에 용어 이름을 입력합니다
-
선택적으로 설정:
- 슬러그 - 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": "하우투 가이드와 튜토리얼"
} 용어 편집
-
분류 체계 용어 페이지로 이동합니다
-
용어 옆의 편집을 클릭합니다
-
이름, 슬러그, 상위 또는 설명을 업데이트합니다
-
저장을 클릭합니다
용어 삭제
-
분류 체계 용어 페이지로 이동합니다
-
용어 옆의 삭제를 클릭합니다
-
삭제를 확인합니다
분류 체계 쿼리
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; // 용어 슬러그 ("news")
label: string; // 표시 라벨 ("News")
parentId?: string;
description?: string;
children: TaxonomyTerm[];
count?: number; // 이 용어를 가진 항목 수
}
count 계산은 분류 체계의 컬렉션에서 모든 콘텐츠-용어 할당을 집계하며, 이는 호출에서 가장 비용이 많이 드는 부분입니다. 라벨과 슬러그만 필요하면 건너뛰세요 — 그러면 count가 반환된 용어에서 생략됩니다:
const tags = await getTaxonomyTerms("tag", { includeCounts: false });
단일 용어 가져오기
다음 예제는 분류 체계와 슬러그로 용어를 가져옵니다:
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"]
}