EmDash 包含媒體庫,用於管理圖片、文件和其他檔案。本指南介紹如何上傳、整理以及在內容中使用媒體。
存取媒體庫
在管理側邊欄點擊 Media 開啟媒體庫。庫中顯示所有已上傳的檔案,包含預覽、檔案名稱和上傳日期。
上傳檔案
從媒體庫上傳
-
在管理側邊欄點擊 Media
-
點擊 Upload 或將檔案拖入上傳區域
-
從電腦中選擇一個或多個檔案
-
等待上傳完成
從內容編輯器上傳
-
在富文本編輯器中點擊圖片按鈕
-
在媒體選擇器中點擊 Upload
-
從電腦選擇檔案
-
新增替代文字後點擊 Insert
支援的檔案類型
EmDash 支援常見的 Web 檔案類型:
| 類別 | 副檔名 |
|---|---|
| 圖片 | .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 ?? ""}
/>
)}
回應式圖片
對於回應式圖片,使用 Astro 的 Image 元件處理外部 URL:
---
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 能夠正確呈現媒體,無論其託管位置如何。