内容导入

本页内容

EmDash 从 WordPress 和其他平台导入内容。每个导入源会检测平台,分析其内容并将其获取到您的站点。

导入源

源 ID平台探测OAuth完整导入
wxrWordPress 导出文件
wordpress-comWordPress.com
wordpress-rest自托管 WordPress仅探测

WXR 文件上传

最完整的导入方法。将 WordPress eXtended RSS (WXR) 导出文件直接上传到管理仪表板。

功能:

  • 所有文章类型(包括自定义)
  • 所有元字段
  • 草稿和私密文章
  • 完整的分类层次结构
  • 媒体附件元数据

如何获取 WXR 文件:

  1. 在 WordPress 管理后台,前往工具 → 导出
  2. 选择所有内容或特定文章类型
  3. 点击下载导出文件
  4. .xml 文件上传到 EmDash

WordPress.com OAuth

对于托管在 WordPress.com 上的站点,通过 OAuth 连接以导入,无需手动导出文件。

  1. 输入您的 WordPress.com 站点 URL
  2. 点击使用 WordPress.com 连接
  3. 在 WordPress.com 弹窗中授权 EmDash
  4. 选择要导入的内容

包含的内容:

  • 已发布和草稿内容
  • 私密文章(需要授权)
  • 通过 API 获取的媒体文件
  • 向 REST API 公开的自定义字段

WordPress REST API 探测

当您输入 URL 时,EmDash 会探测站点以检测 WordPress 并显示可用内容:

检测到: WordPress 6.4
├── 文章: 127 (已发布)
├── 页面: 12 (已发布)
└── 媒体: 89 个文件

注意: 草稿和私密内容需要身份验证
或完整的 WXR 导出。

REST 探测仅供参考。对于完整导入,它建议上传 WXR 文件或通过 OAuth 连接(对于 WordPress.com)。

导入流程

所有源都遵循相同的流程:

┌─────────────┐     ┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│     连接    │────▶│     分析    │────▶│     准备    │────▶│     执行    │
│  (探测/     │     │  (模式      │     │  (创建      │     │  (导入      │
│   上传)     │     │   检查)     │     │   模式)     │     │   内容)     │
└─────────────┘     └─────────────┘     └─────────────┘     └─────────────┘

步骤 1: 连接

输入 URL 进行探测或直接上传文件。

URL 探测并行运行所有已注册的源。置信度最高的匹配决定建议的下一步操作:

  • WordPress.com 站点 → 提供 OAuth 连接
  • 自托管 WordPress → 显示导出说明
  • 未知 → 建议文件上传

步骤 2: 分析

源解析内容并检查模式兼容性:

文章类型:
├── post (127) → posts [新集合]
├── page (12)  → pages [现有,兼容]
├── product (45) → products [添加 3 个字段]
└── revision (234) → [跳过 - 内部类型]

所需的模式更改:
├── 创建集合: posts
├── 向 pages 添加字段: featured_image
└── 创建集合: products

每种文章类型显示其状态:

状态含义
就绪集合存在且字段兼容
新集合将自动创建
添加字段集合存在,添加缺失的字段
不兼容字段类型冲突(需要手动修复)

步骤 3: 准备模式

点击创建模式并导入以:

  1. 创建新集合
  2. 使用正确的列类型添加缺失的字段
  3. 设置带索引的内容表

步骤 4: 执行导入

内容按顺序导入:

  • Gutenberg/HTML 转换为 Portable Text
  • WordPress 状态映射到 EmDash 状态
  • WordPress 作者映射到所有权(authorId)和展示署名
  • 创建并链接分类
  • 可重用区块(wp_block)作为部分导入
  • 实时显示进度

作者导入行为:

  • 如果作者映射指向 EmDash 用户,则将所有权设置为该用户,并为同一用户创建/重用链接的署名。
  • 如果没有用户映射,则从 WordPress 作者身份创建/重用访客署名。
  • 导入的条目获得有序的署名信用,第一个信用设置为 primaryBylineId

步骤 5: 媒体导入(可选)

在内容之后,可选择导入媒体:

  1. 分析 — 按类型显示附件计数

    找到的媒体:
    ├── 图片: 75 个文件
    ├── 视频: 10 个文件
    └── 其他: 4 个文件
  2. 下载 — 从 WordPress URL 流式传输并显示进度

    正在导入媒体...
    ├── 45 / 89 (50%)
    ├── 当前: vacation-photo.jpg
    └── 状态: 上传中
  3. 重写 URL — 内容自动更新为新 URL

媒体导入使用内容哈希(xxHash64)进行去重。在多个文章中使用的相同图片只存储一次。

API 端点

导入系统公开这些端点:

探测 URL

通过探测请求检测 URL 背后的平台:

POST /_emdash/api/import/probe
Content-Type: application/json

{ "url": "https://example.com" }

响应包含检测到的平台和建议的操作。

分析 WXR

上传 WXR 文件以分析其文章类型和模式兼容性:

POST /_emdash/api/import/wordpress/analyze
Content-Type: multipart/form-data

file: [WordPress export .xml]

响应包含带模式兼容性的文章类型分析。

准备模式

为选定的文章类型创建集合和字段:

POST /_emdash/api/import/wordpress/prepare
Content-Type: application/json

{
  "postTypes": [
    { "name": "post", "collection": "posts", "enabled": true }
  ]
}

执行导入

将内容导入映射的集合:

POST /_emdash/api/import/wordpress/execute
Content-Type: multipart/form-data

file: [WordPress export .xml]
config: { "postTypeMappings": { "post": { "collection": "posts" } } }

导入媒体

下载并存储导入引用的媒体附件:

POST /_emdash/api/import/wordpress/media
Content-Type: application/json

{
  "attachments": [{ "id": 123, "url": "https://..." }],
  "stream": true
}

响应在下载和上传期间流式传输 NDJSON 进度更新。

重写 URL

将导入内容中的旧媒体 URL 替换为其存储的等效项:

POST /_emdash/api/import/wordpress/rewrite-urls
Content-Type: application/json

{
  "urlMap": { "https://old.com/image.jpg": "/_emdash/media/abc123" }
}

错误处理

可恢复的错误

  • 网络超时 — 使用退避重试
  • 单个项目解析失败 — 记录,跳过,导入继续
  • 媒体下载失败 — 标记为手动处理

致命错误

  • 无效的文件格式 — 导入停止并显示错误消息
  • 数据库连接丢失 — 导入暂停,允许恢复
  • 存储配额超出 — 导入停止,显示使用情况

错误报告

导入完成后,EmDash 显示成功、调整和失败的摘要:

导入完成

✓ 已导入 125 篇文章
✓ 已导入 12 个页面
✓ 已记录 85 个媒体引用

⚠ 2 个项目有警告:
  - 文章 "Special Characters ñ" - 标题编码已修复
  - 页面 "About" - 重复的 slug 已重命名为 "about-1"

✗ 1 个项目失败:
  - 文章 ID 456 - 内容解析错误(已保存为草稿)

失败的项目保存为草稿,原始内容在 _importError 中供审查。

自定义源

要从内置源未涵盖的平台导入,实现 ImportSource 接口并在集成上注册:

import { mySource } from "./src/import/custom-source";

export default defineConfig({
	integrations: [
		emdash({
			import: { sources: [mySource] },
		}),
	],
});

接口(probeanalyzefetchContent)和规范化的输出形状记录在架构(内部)中。

下一步