분류 체계

이 페이지

분류 체계는 콘텐츠를 정리하기 위한 분류 시스템입니다. EmDash는 내장된 카테고리와 태그를 포함하며, 전문적인 분류 요구 사항을 위한 커스텀 분류 체계를 지원합니다.

내장 분류 체계

EmDash는 두 가지 기본 분류 체계를 제공합니다:

분류 체계유형설명
카테고리계층형부모-자식 관계를 가진 중첩 분류
태그평면형계층 구조가 없는 간단한 레이블

둘 다 기본적으로 게시물 컬렉션에서 사용할 수 있습니다.

용어 관리

용어 생성

Admin Dashboard

  1. 분류 체계 페이지로 이동합니다 (예: /_emdash/admin/taxonomies/category)

  2. 새로 추가 양식에 용어 이름을 입력합니다

  3. 선택적으로 설정:

    • 슬러그 - URL 식별자 (이름에서 자동 생성)
    • 부모 - 계층형 분류 체계용
    • 설명 - 용어 설명
  4. 추가를 클릭합니다

Content Editor

  1. 편집기에서 콘텐츠 항목을 엽니다

  2. 사이드바에서 분류 체계 패널을 찾습니다

  3. 카테고리의 경우, 해당 용어의 확인란을 선택하거나 + 새로 추가를 클릭합니다

  4. 태그의 경우, 쉼표로 구분하여 태그 이름을 입력합니다

  5. 콘텐츠를 저장합니다

API

다음 요청은 category 분류 체계에 용어를 생성합니다:

POST /_emdash/api/taxonomies/category/terms
Content-Type: application/json
Authorization: Bearer YOUR_API_TOKEN

{
  "slug": "tutorials",
  "label": "Tutorials",
  "parentId": "term_abc",
  "description": "How-to guides and tutorials"
}

용어 편집

  1. 분류 체계 용어 페이지로 이동합니다

  2. 용어 옆의 편집을 클릭합니다

  3. 이름, 슬러그, 부모 또는 설명을 업데이트합니다

  4. 저장을 클릭합니다

용어 삭제

  1. 분류 체계 용어 페이지로 이동합니다

  2. 용어 옆의 삭제를 클릭합니다

  3. 삭제를 확인합니다

분류 체계 쿼리

EmDash는 분류 체계 용어를 쿼리하고 용어로 콘텐츠를 필터링하는 함수를 제공합니다.

모든 용어 가져오기

분류 체계의 모든 용어를 검색:

import { getTaxonomyTerms } from "emdash";

// Get all categories (returns tree structure)
const categories = await getTaxonomyTerms("category");

// Get all tags (returns flat list)
const tags = await getTaxonomyTerms("tag");

계층형 분류 체계의 경우, 용어에는 children 배열이 포함됩니다:

interface TaxonomyTerm {
	id: string;
	name: string; // Taxonomy name ("category")
	slug: string; // Term slug ("news")
	label: string; // Display label ("News")
	parentId?: string;
	description?: string;
	children: TaxonomyTerm[];
	count?: number; // Number of entries with this term
}

단일 용어 가져오기

다음 예제는 분류 체계와 슬러그로 하나의 용어를 가져옵니다:

import { getTerm } from "emdash";

const category = await getTerm("category", "news");
// Returns TaxonomyTerm or null

항목의 용어 가져오기

다음 예제는 단일 항목에 할당된 카테고리와 태그를 검색합니다:

import { getEntryTerms } from "emdash";

// Get all categories for a post
const categories = await getEntryTerms("posts", "post-123", "category");

// Get all tags for a post
const tags = await getEntryTerms("posts", "post-123", "tag");

용어로 콘텐츠 필터링

where 필터와 함께 getEmDashCollection 사용:

import { getEmDashCollection } from "emdash";

// Posts in the "news" category
const { entries: newsPosts } = await getEmDashCollection("posts", {
	status: "published",
	where: { category: "news" },
});

// Posts with the "javascript" tag
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");

  // Flatten hierarchical tree for routing
  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} posts</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={`Posts tagged "${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>Categories</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");

// Calculate font sizes based on count
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>Posted in:</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": "Genres",
  "labelSingular": "Genre",
  "hierarchical": true,
  "collections": ["books", "movies"]
}

커스텀 분류 체계 사용

내장 분류 체계와 동일한 방식으로 커스텀 분류 체계를 쿼리하고 표시:

import { getTaxonomyTerms, getEmDashCollection } from "emdash";

// Get all genres
const genres = await getTaxonomyTerms("genre");

// Get books in a genre
const { entries: sciFiBooks } = await getEmDashCollection("books", {
	where: { genre: "science-fiction" },
});

컬렉션에 할당

분류 체계는 적용되는 컬렉션을 지정합니다:

{
  "name": "difficulty",
  "label": "Difficulty Levels",
  "hierarchical": false,
  "collections": ["recipes", "tutorials"]
}

분류 체계 API 참조

REST 엔드포인트

엔드포인트메서드설명
/_emdash/api/taxonomiesGET분류 체계 정의 나열
/_emdash/api/taxonomiesPOST분류 체계 생성
/_emdash/api/taxonomies/:name/termsGET용어 나열
/_emdash/api/taxonomies/:name/termsPOST용어 생성
/_emdash/api/taxonomies/:name/terms/:slugGET용어 가져오기
/_emdash/api/taxonomies/:name/terms/:slugPUT용어 업데이트
/_emdash/api/taxonomies/:name/terms/:slugDELETE용어 삭제

콘텐츠에 용어 할당

다음 요청은 게시물에 카테고리 용어를 할당합니다:

POST /_emdash/api/content/posts/post-123/terms/category
Content-Type: application/json
Authorization: Bearer YOUR_API_TOKEN

{
  "termIds": ["term_news", "term_featured"]
}

다음 단계