미디어 라이브러리

이 페이지

EmDash에는 이미지, 문서 및 기타 파일을 관리하기 위한 미디어 라이브러리가 포함되어 있습니다. 이 가이드는 콘텐츠에서 미디어를 업로드, 정리 및 사용하는 방법을 다룹니다.

미디어 라이브러리 접근

관리자 사이드바에서 Media를 클릭하여 미디어 라이브러리를 엽니다. 라이브러리는 업로드된 모든 파일을 미리보기, 파일명 및 업로드 날짜와 함께 표시합니다.

업로드 버튼이 있는 이미지 그리드를 보여주는 EmDash 미디어 라이브러리

파일 업로드

미디어 라이브러리에서

  1. 관리자 사이드바에서 Media 클릭

  2. Upload를 클릭하거나 업로드 영역에 파일을 드래그

  3. 컴퓨터에서 하나 이상의 파일 선택

  4. 업로드 완료 대기

콘텐츠 편집기에서

  1. 리치 텍스트 편집기에서 이미지 버튼 클릭

  2. 미디어 선택기에서 Upload 클릭

  3. 컴퓨터에서 파일 선택

  4. 대체 텍스트를 추가하고 삽입 클릭

지원되는 파일 유형

EmDash는 일반적인 웹 파일 유형을 지원합니다:

카테고리확장자
이미지.jpg, .jpeg, .png, .gif, .webp, .avif, .svg
문서.pdf, .doc, .docx, .xls, .xlsx, .ppt, .pptx
동영상.mp4, .webm, .mov
오디오.mp3, .wav, .ogg

스토리지 백엔드

EmDash는 여러 스토리지 백엔드를 지원합니다. Astro 설정에서 스토리지를 구성합니다:

로컬 스토리지

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 호환

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을 사용합니다:

  1. 클라이언트가 API에서 업로드 URL을 요청

  2. 서버가 만료 시간이 있는 서명된 URL을 생성

  3. 클라이언트가 서명된 URL을 사용하여 스토리지에 직접 업로드

  4. 서버가 파일 메타데이터를 데이터베이스에 기록

이 접근 방식은 대용량 파일을 애플리케이션 서버에서 분리하고 클라우드 스토리지로의 직접 업로드를 가능하게 합니다.

미디어 정리

폴더

폴더를 만들어 미디어를 정리합니다:

  1. 미디어 라이브러리에서 New Folder 클릭

  2. 폴더 이름 입력

  3. 만들기 클릭

  4. 파일을 폴더로 드래그하여 정리

검색

검색 상자를 사용하여 이름으로 파일을 찾습니다. 검색은 부분 파일명도 일치합니다.

필터

미디어 필터링:

  • 유형 - 이미지, 문서, 동영상, 오디오
  • 날짜 - 업로드 날짜 범위
  • 폴더 - 특정 폴더

콘텐츠에서 미디어 사용

리치 텍스트 편집기에서

  1. 이미지를 배치할 위치에 커서를 놓기

  2. 도구 모음의 이미지 버튼 클릭

  3. 미디어 라이브러리에서 이미지를 선택하거나 새 이미지를 업로드

  4. 대체 텍스트 입력

  5. 삽입 클릭

대표 이미지로

  1. 편집기에서 콘텐츠 항목 열기

  2. 사이드바에서 Featured Image 필드 찾기

  3. 이미지 선택 클릭

  4. 미디어 라이브러리에서 선택 또는 업로드

  5. 저장 클릭

사용자 정의 필드에서

이미지 또는 파일 유형으로 구성된 필드의 경우, 필드를 클릭하여 미디어 선택기를 엽니다.

템플릿에서 미디어 표시

콘텐츠 데이터에서 미디어 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 ?? ""}
  />
)}

반응형 이미지

EmDash 미디어 필드에는 emdash/uiImage 컴포넌트를 사용합니다:

---
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}
    priority
  />
)}

priority는 첫 화면의 주요 이미지용입니다. loading="eager"fetchpriority="high"를 설정합니다. loading은 로딩을 지연시킬지 여부를 제어하고, fetchpriority는 브라우저에 요청의 우선순위 힌트를 제공합니다.

미디어 삭제

  1. 삭제할 파일 선택

  2. 삭제 클릭

  3. 삭제 확인

미디어 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({
      // ... 데이터베이스, 스토리지 구성
      mediaProviders: [
        cloudflareImages({
          accountId: import.meta.env.CF_ACCOUNT_ID,
          apiToken: import.meta.env.CF_IMAGES_TOKEN,
          // 선택사항: 사용자 정의 전달 도메인
          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({
      // ... 데이터베이스, 스토리지 구성
      mediaProviders: [
        cloudflareStream({
          accountId: import.meta.env.CF_ACCOUNT_ID,
          apiToken: import.meta.env.CF_STREAM_TOKEN,
          // 선택사항: 플레이어 설정
          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;    // 프로바이더 ID, 기본값 "local"
  id: string;           // 프로바이더별 ID
  src?: string;         // 직접 URL (로컬 미디어 또는 일반 문자열 값용)
  previewUrl?: string;  // 관리자 표시용 미리보기 URL (외부 프로바이더)
  filename?: string;    // 원본 파일명
  mimeType?: string;    // MIME 타입
  width?: number;       // 이미지/동영상 너비
  height?: number;      // 이미지/동영상 높이
  alt?: string;         // 대체 텍스트
  meta?: Record<string, unknown>; // 프로바이더별 메타데이터
}

이를 통해 EmDash는 호스팅 위치에 관계없이 미디어를 올바르게 렌더링할 수 있습니다.

다음 단계