EmDash는 이미지, 문서 및 기타 파일을 관리하기 위한 미디어 라이브러리를 포함합니다. 이 가이드에서는 미디어 업로드, 정리 및 콘텐츠에서 사용하는 방법을 다룹니다.
미디어 라이브러리 액세스
관리 사이드바에서 Media를 클릭하여 미디어 라이브러리를 엽니다. 라이브러리는 미리보기, 파일 이름 및 업로드 날짜와 함께 업로드된 모든 파일을 표시합니다.
파일 업로드
미디어 라이브러리에서
-
관리 사이드바에서 Media를 클릭합니다
-
Upload를 클릭하거나 파일을 업로드 영역으로 드래그합니다
-
컴퓨터에서 하나 이상의 파일을 선택합니다
-
업로드가 완료될 때까지 기다립니다
콘텐츠 편집기에서
-
리치 텍스트 편집기에서 이미지 버튼을 클릭합니다
-
미디어 선택기에서 Upload를 클릭합니다
-
컴퓨터에서 파일을 선택합니다
-
대체 텍스트를 추가하고 Insert를 클릭합니다
지원되는 파일 형식
EmDash는 일반적인 웹 파일 형식을 지원합니다:
| 카테고리 | 확장자 |
|---|---|
| 이미지 | .jpg, .jpeg, .png, .gif, .webp, .avif, .svg |
| 문서 | .pdf, .doc, .docx, .xls, .xlsx, .ppt, .pptx |
| 비디오 | .mp4, .webm, .mov |
| 오디오 | .mp3, .wav, .ogg |
스토리지 백엔드
EmDash는 여러 스토리지 백엔드를 지원합니다. Astro 구성에서 스토리지를 구성합니다:
Local Storage
import { defineConfig } from "astro/config";
import emdash, { local } from "emdash/astro";
export default defineConfig({
integrations: [
emdash({
storage: local({
directory: "./uploads",
baseUrl: "/_emdash/api/media/file",
}),
}),
],
});파일은 ./uploads 디렉토리에 저장됩니다. 개발 및 단일 서버 배포에 적합합니다.
Cloudflare R2
import { defineConfig } from "astro/config";
import emdash from "emdash/astro";
import { r2 } from "@emdash-cms/cloudflare";
export default defineConfig({
integrations: [
emdash({
storage: r2({
binding: "MEDIA_BUCKET",
publicUrl: "https://media.example.com",
}),
}),
],
});wrangler.jsonc에 구성된 R2 버킷이 필요합니다:
{
"r2_buckets": [
{
"binding": "MEDIA_BUCKET",
"bucket_name": "my-media-bucket",
},
],
} S3-Compatible
import { defineConfig } from "astro/config";
import emdash, { s3 } from "emdash/astro";
export default defineConfig({
integrations: [
emdash({
storage: s3({
endpoint: "https://s3.amazonaws.com",
bucket: "my-media-bucket",
accessKeyId: process.env.S3_ACCESS_KEY_ID,
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY,
region: "us-east-1",
publicUrl: "https://media.example.com",
}),
}),
],
});Cloudflare R2(S3 API 통해), MinIO 및 기타 S3 호환 서비스와 함께 작동합니다.
업로드 작동 방식
EmDash는 보안 업로드를 위해 서명된 URL을 사용합니다:
-
클라이언트가 API에서 업로드 URL을 요청합니다
-
서버가 만료 기간이 있는 서명된 URL을 생성합니다
-
클라이언트가 서명된 URL을 사용하여 스토리지에 직접 업로드합니다
-
서버가 데이터베이스에 파일 메타데이터를 기록합니다
이 접근 방식은 대용량 파일을 애플리케이션 서버에서 분리하고 클라우드 스토리지로의 직접 업로드를 가능하게 합니다.
미디어 정리
폴더
폴더를 만들어 미디어를 정리합니다:
-
미디어 라이브러리에서 New Folder를 클릭합니다
-
폴더 이름을 입력합니다
-
Create를 클릭합니다
-
파일을 폴더로 드래그하여 정리합니다
검색
검색 상자를 사용하여 이름으로 파일을 찾습니다. 검색은 부분 파일 이름과 일치합니다.
필터
다음 기준으로 미디어를 필터링합니다:
- Type - 이미지, 문서, 비디오, 오디오
- Date - 업로드 날짜 범위
- Folder - 특정 폴더
콘텐츠에서 미디어 사용
리치 텍스트 편집기에서
-
이미지를 원하는 위치에 커서를 놓습니다
-
도구 모음에서 이미지 버튼을 클릭합니다
-
미디어 라이브러리에서 이미지를 선택하거나 새 이미지를 업로드합니다
-
대체 텍스트를 입력합니다
-
Insert를 클릭합니다
추천 이미지로
-
편집기에서 콘텐츠 항목을 엽니다
-
사이드바에서 Featured Image 필드를 찾습니다
-
Select Image를 클릭합니다
-
미디어 라이브러리에서 선택하거나 업로드합니다
-
Save를 클릭합니다
사용자 정의 필드에서
이미지 또는 파일 유형으로 구성된 필드의 경우 필드를 클릭하여 미디어 선택기를 엽니다.
템플릿에서 미디어 표시
콘텐츠 데이터에서 미디어 URL에 액세스합니다:
---
import { getEmDashEntry } from "emdash";
const { entry: post } = await getEmDashEntry("posts", Astro.params.slug);
---
{post?.data.featured_image && (
<img
src={post.data.featured_image}
alt={post.data.featured_image_alt ?? ""}
/>
)}
반응형 이미지
반응형 이미지의 경우 외부 URL과 함께 Astro의 Image 컴포넌트를 사용합니다:
---
import { Image } from "astro:assets";
import { getEmDashEntry } from "emdash";
const { entry: post } = await getEmDashEntry("posts", Astro.params.slug);
---
{post?.data.featured_image && (
<Image
src={post.data.featured_image}
alt={post.data.featured_image_alt ?? ""}
width={800}
height={450}
/>
)}
미디어 삭제
-
삭제할 파일을 선택합니다
-
Delete를 클릭합니다
-
삭제를 확인합니다
미디어 API
관리 API를 사용하여 프로그래밍 방식으로 미디어에 액세스합니다.
파일 업로드
미디어를 멀티파트 폼 데이터로 업로드합니다:
POST /_emdash/api/media
Content-Type: multipart/form-data
Authorization: Bearer YOUR_API_TOKEN
file=<binary file data>
성공적인 업로드는 저장된 미디어 항목을 반환합니다:
{
"success": true,
"data": {
"item": {
"id": "01ABC123",
"filename": "hero-image.jpg",
"mime_type": "image/jpeg",
"storage_key": "media/abc123/hero-image.jpg",
"width": 1200,
"height": 800
}
}
}
미디어 나열
다음 요청은 접두사 아래의 미디어를 나열합니다:
GET /_emdash/api/media?prefix=images/&limit=20
Authorization: Bearer YOUR_API_TOKEN
미디어 삭제
다음 요청은 저장된 파일을 삭제합니다:
DELETE /_emdash/api/media/images/hero.jpg
Authorization: Bearer YOUR_API_TOKEN
미디어 제공자
로컬 스토리지 외에도 EmDash는 전문 이미지 및 비디오 호스팅을 위한 외부 미디어 제공자를 지원합니다. 미디어 제공자는 미디어 선택기의 탭으로 나타나 편집자가 여러 소스에서 선택할 수 있습니다.
사용 가능한 제공자
Cloudflare Images
Cloudflare Images는 자동 최적화, 크기 조정 및 형식 변환을 제공하는 이미지 호스팅을 제공합니다.
import { defineConfig } from "astro/config";
import emdash from "emdash/astro";
import { cloudflareImages } from "@emdash-cms/cloudflare";
export default defineConfig({
integrations: [
emdash({
// ... database, storage config
mediaProviders: [
cloudflareImages({
accountId: import.meta.env.CF_ACCOUNT_ID,
apiToken: import.meta.env.CF_IMAGES_TOKEN,
// Optional: custom delivery domain
deliveryDomain: "images.example.com",
}),
],
}),
],
});기능:
- 관리자에서 직접 이미지 찾아보기 및 업로드
- 자동 이미지 최적화 및 형식 변환
- URL 기반 변환(크기 조정, 자르기, 형식)
- 반응형 이미지를 위한 유연한 변형
Cloudflare Stream
Cloudflare Stream은 HLS/DASH 적응형 스트리밍을 제공하는 비디오 호스팅을 제공합니다.
import { defineConfig } from "astro/config";
import emdash from "emdash/astro";
import { cloudflareStream } from "@emdash-cms/cloudflare";
export default defineConfig({
integrations: [
emdash({
// ... database, storage config
mediaProviders: [
cloudflareStream({
accountId: import.meta.env.CF_ACCOUNT_ID,
apiToken: import.meta.env.CF_STREAM_TOKEN,
// Optional: player settings
controls: true,
autoplay: false,
loop: false,
}),
],
}),
],
});기능:
- 관리자에서 비디오 찾아보기, 검색 및 업로드
- HLS 및 DASH 적응형 스트리밍
- 자동 썸네일 생성
- 대용량 파일의 직접 업로드
여러 제공자 사용
여러 제공자를 구성할 수 있습니다. 각각은 미디어 선택기의 탭으로 나타납니다:
import { defineConfig } from "astro/config";
import emdash from "emdash/astro";
import { cloudflareImages, cloudflareStream } from "@emdash-cms/cloudflare";
export default defineConfig({
integrations: [
emdash({
database: d1({ binding: "DB" }),
storage: r2({ binding: "MEDIA" }),
mediaProviders: [
cloudflareImages({
accountId: import.meta.env.CF_ACCOUNT_ID,
apiToken: import.meta.env.CF_IMAGES_TOKEN,
}),
cloudflareStream({
accountId: import.meta.env.CF_ACCOUNT_ID,
apiToken: import.meta.env.CF_STREAM_TOKEN,
}),
],
}),
],
});
로컬 미디어 라이브러리(“Library” 탭)는 구성된 제공자와 함께 항상 사용할 수 있습니다.
제공자 미디어 렌더링
Image 컴포넌트를 사용하여 미디어를 렌더링합니다:
---
import { Image } from "emdash/ui";
import { getEmDashEntry } from "emdash";
const { entry: post } = await getEmDashEntry("posts", Astro.params.slug);
---
{post?.data.featured_image && (
<Image
image={post.data.featured_image}
width={800}
height={450}
/>
)}
컴포넌트는 자동으로:
- 저장된 값에서 제공자를 감지합니다
- 최적화된
<img>요소를 렌더링합니다 - 제공자별 최적화를 적용합니다(예: Cloudflare Images 변환)
MediaValue 타입
미디어 필드는 제공자 정보를 포함하는 MediaValue 객체를 저장합니다:
interface MediaValue {
provider?: string; // Provider ID, defaults to "local"
id: string; // Provider-specific ID
src?: string; // Direct URL (for local media or plain-string values)
previewUrl?: string; // Preview URL for admin display (external providers)
filename?: string; // Original filename
mimeType?: string; // MIME type
width?: number; // Image/video width
height?: number; // Image/video height
alt?: string; // Alt text
meta?: Record<string, unknown>; // Provider-specific metadata
}
이를 통해 EmDash는 호스팅 위치에 관계없이 미디어를 올바르게 렌더링할 수 있습니다.