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 能够正确渲染媒体,无论其托管位置如何。