컬렉션과 필드

이 페이지

컬렉션(collection)은 콘텐츠 유형(게시물, 페이지, 제품)입니다. 필드 정의는 각 항목의 데이터 구조를 설정합니다.

컬렉션 생성

관리 패널의 콘텐츠 타입에서 컬렉션을 생성합니다. 각 컬렉션에는 다음 속성이 있습니다:

페이지, 게시물 및 사용자 지정 컬렉션과 기능을 표시하는 EmDash 콘텐츠 타입
속성설명
slugURL 안전 식별자(예: posts, products)
label표시 이름(예: “블로그 게시물”)
labelSingular단수형(예: “게시물”)
description편집자를 위한 선택적 설명
icon관리 사이드바용 Lucide 아이콘 이름
supports초안, 리비전, 미리보기, 예약, 검색, SEO와 같은 기능

컬렉션 기능

컬렉션을 생성할 때 필요한 기능을 활성화하세요:

기능설명
drafts초안/게시 워크플로우 활성화
revisions버전 스냅샷으로 콘텐츠 이력 추적
preview초안 콘텐츠용 서명된 미리보기 URL 생성
scheduling미래 날짜에 콘텐츠 게시 예약

다음 컬렉션은 네 가지 기능을 모두 활성화합니다:

{
  slug: "posts",
  label: "Blog Posts",
  labelSingular: "Post",
  supports: ["drafts", "revisions", "preview", "scheduling"]
}

필드 타입

EmDash는 SQLite 열 타입에 매핑되는 16가지 필드 타입을 지원합니다.

텍스트 필드

string

짧은 텍스트 입력. TEXT 열에 매핑됩니다.

{ slug: "title", type: "string", label: "Title" }

text

여러 줄 텍스트 영역. TEXT 열에 매핑됩니다.

{ slug: "excerpt", type: "text", label: "Excerpt" }

slug

URL 안전 슬러그 필드. TEXT 열에 매핑됩니다.

{ slug: "handle", type: "slug", label: "URL Handle" }

리치 콘텐츠

portableText

리치 텍스트 에디터(TipTap/ProseMirror). JSON으로 저장됩니다.

{ slug: "content", type: "portableText", label: "Content" }

Portable Text는 HTML을 내장하지 않고 구조를 보존하는 블록 기반 형식입니다.

json

임의의 JSON 데이터. JSON으로 저장됩니다.

{ slug: "metadata", type: "json", label: "Custom Metadata" }

숫자

number

소수. REAL 열에 매핑됩니다.

{ slug: "price", type: "number", label: "Price" }

integer

정수. INTEGER 열에 매핑됩니다.

{ slug: "quantity", type: "integer", label: "Stock Quantity" }

불리언과 날짜

boolean

참/거짓 토글. INTEGER(0/1)에 매핑됩니다.

{ slug: "featured", type: "boolean", label: "Featured Post" }

datetime

날짜 및 시간 선택기. ISO 8601 문자열로 저장됩니다.

{ slug: "eventDate", type: "datetime", label: "Event Date" }

선택

select

목록에서 단일 옵션. TEXT 열에 매핑됩니다.

{
  slug: "status",
  type: "select",
  label: "Product Status",
  validation: {
    options: ["active", "discontinued", "coming_soon"]
  }
}

multiSelect

목록에서 여러 옵션. JSON 배열로 저장됩니다.

{
  slug: "features",
  type: "multiSelect",
  label: "Product Features",
  validation: {
    options: ["wireless", "waterproof", "eco-friendly"]
  }
}

미디어 및 참조

image

미디어 라이브러리의 이미지 선택기. 미디어 ID를 TEXT로 저장합니다.

{ slug: "featuredImage", type: "image", label: "Featured Image" }

file

미디어 라이브러리의 파일 선택기. 미디어 ID를 TEXT로 저장합니다.

{ slug: "attachment", type: "file", label: "PDF Attachment" }

reference

다른 컬렉션의 항목 참조. 항목 ID를 TEXT로 저장합니다.

{
  slug: "author",
  type: "reference",
  label: "Author",
  options: {
    collection: "authors"
  }
}

필드 속성

모든 필드는 다음 속성을 지원합니다:

속성타입설명
slugstring데이터베이스의 열 이름
labelstring관리 UI의 표시 레이블
typeFieldType16가지 필드 타입 중 하나
requiredboolean필드에 값이 필요한지 여부
uniqueboolean값이 항목 간에 고유해야 하는지 여부
defaultValueunknown새 항목의 기본값
validationobject타입별 검증 규칙
widgetstring사용자 정의 위젯 식별자
optionsobject위젯별 구성
sortOrdernumber편집기의 표시 순서

검증 규칙

validation 객체는 필드 타입에 따라 다릅니다. 전체 형식은 다음과 같습니다:

interface FieldValidation {
	required?: boolean; // All types
	min?: number; // number, integer
	max?: number; // number, integer
	minLength?: number; // string, text
	maxLength?: number; // string, text
	pattern?: string; // string (regex)
	options?: string[]; // select, multiSelect
}

다음 필드는 패턴과 일치하는 고유한 이메일 주소가 필요합니다:

{
  slug: "email",
  type: "string",
  label: "Email Address",
  required: true,
  unique: true,
  validation: {
    pattern: "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"
  }
}

위젯 옵션

options 객체는 필드별 UI 동작을 구성합니다. 전체 형식은 다음과 같습니다:

interface FieldWidgetOptions {
	rows?: number; // text (textarea rows)
	showPreview?: boolean; // image, file
	collection?: string; // reference (target collection)
	allowMultiple?: boolean; // reference (multiple refs)
	[key: string]: unknown; // Custom widget options
}

다음 참조 필드는 여러 제품을 연결합니다:

{
  slug: "relatedProducts",
  type: "reference",
  label: "Related Products",
  options: {
    collection: "products",
    allowMultiple: true
  }
}

컬렉션 쿼리

제공된 쿼리 함수를 사용하여 콘텐츠를 가져옵니다. 이들은 Astro의 라이브 컬렉션 패턴을 따르며 구조화된 결과를 반환합니다. 다음 예제는 일반적인 쿼리 옵션을 보여줍니다:

import { getEmDashCollection, getEmDashEntry } from "emdash";

// Get all entries - returns { entries, error }
const { entries: posts } = await getEmDashCollection("posts");

// Filter by status
const { entries: drafts } = await getEmDashCollection("posts", {
	status: "draft",
});

// Limit results
const { entries: recent } = await getEmDashCollection("posts", {
	limit: 5,
});

// Filter by taxonomy
const { entries: newsPosts } = await getEmDashCollection("posts", {
	where: { category: "news" },
});

// Get a single entry by slug - returns { entry, error, isPreview }
const { entry: post } = await getEmDashEntry("posts", "my-post-slug");

// Handle errors
const { entries, error } = await getEmDashCollection("posts");
if (error) {
	console.error("Failed to load posts:", error);
}

타입 생성

스키마에서 TypeScript 타입을 생성하려면 npx emdash types를 실행하세요. 생성된 파일에는 컬렉션당 하나의 인터페이스가 포함됩니다:

export interface Post {
	title: string;
	content: PortableTextBlock[];
	excerpt?: string;
	featuredImage?: string;
	author: string; // reference ID
}

export interface Product {
	title: string;
	price: number;
	description: PortableTextBlock[];
}

데이터베이스 매핑

필드 타입은 다음과 같이 SQLite 열 타입에 매핑됩니다:

필드 타입SQLite 타입비고
stringTEXT
textTEXT
slugTEXT
urlTEXT
numberREAL64비트 부동 소수점
integerINTEGER64비트 부호 있는 정수
booleanINTEGER0 또는 1
datetimeTEXTISO 8601 형식
selectTEXT
multiSelectJSON문자열 배열
portableTextJSON블록 배열
imageTEXT미디어 ID
fileTEXT미디어 ID
referenceTEXT항목 ID
jsonJSON임의의 JSON
repeaterJSON하위 필드 배열

다음 단계