EmDash 包含一个用于管理图片、文档和其他文件的媒体库。本指南涵盖在内容中上传、组织和使用媒体。
访问媒体库
通过管理侧边栏点击 Media 打开媒体库。媒体库显示所有已上传的文件,包括预览、文件名和上传日期。
上传文件
从媒体库上传
-
点击管理侧边栏中的 Media
-
点击 Upload 或将文件拖拽到上传区域
-
从计算机中选择一个或多个文件
-
等待上传完成
从内容编辑器上传
-
在富文本编辑器中,点击图片按钮
-
在媒体选择器中点击 Upload
-
从计算机中选择文件
-
添加替代文本并点击 插入
支持的文件类型
EmDash 支持常见的 Web 文件类型:
| 类别 | 扩展名 |
|---|---|
| 图片 | .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 进行安全上传:
-
客户端向 API 请求上传 URL
-
服务器生成带有过期时间的签名 URL
-
客户端使用签名 URL 直接上传到存储
-
服务器将文件元数据记录到数据库
这种方式将大文件从应用服务器分离,并支持直接上传到云存储。
组织媒体
文件夹
创建文件夹来组织您的媒体:
-
在媒体库中点击 New Folder
-
输入文件夹名称
-
点击 创建
-
将文件拖入文件夹进行组织
搜索
使用搜索框按名称查找文件。搜索可匹配部分文件名。
筛选
按以下条件筛选媒体:
- 类型 - 图片、文档、视频、音频
- 日期 - 上传日期范围
- 文件夹 - 特定文件夹
在内容中使用媒体
在富文本编辑器中
-
将光标放在您要插入图片的位置
-
点击工具栏中的图片按钮
-
从媒体库选择图片或上传新图片
-
输入替代文本
-
点击 插入
作为特色图片
-
在编辑器中打开内容条目
-
在侧边栏找到 Featured Image 字段
-
点击 选择图片
-
从媒体库选择或上传
-
点击 保存
在自定义字段中
对于配置为图片或文件类型的字段,点击该字段打开媒体选择器。
在模板中显示媒体
从内容数据中访问媒体 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/ui 中的 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}
priority
/>
)}
priority 用于首屏主图片。它设置 loading="eager" 和 fetchpriority="high":loading 控制是否延迟加载,fetchpriority 给浏览器提供请求优先级提示。
删除媒体
-
选择要删除的文件
-
点击 删除
-
确认删除
媒体 API
通过管理 API 以编程方式访问媒体。
上传文件
以 multipart 表单数据形式上传媒体:
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 能够正确渲染媒体,无论其托管在何处。