EmDash 通过位于 /_emdash/admin/import/wordpress 的 Import from WordPress 页面导入 WordPress 内容。导入器可以分析 WordPress eXtended RSS(WXR)文件,也可以连接到运行 EmDash Exporter 插件的站点。
导入源
源注册表中包含三个 WordPress 源:
| 源 ID | 输入 | 导入内容 | 访问范围 |
|---|---|---|---|
wxr | WordPress 导出的 .xml 文件 | 是 | 导出文件中包含的数据 |
wordpress-plugin | 站点 URL 加 EmDash Exporter 凭据 | 是 | 导出器端点,包括需要认证的内容 |
wordpress-rest | 公开的站点 URL | 否 | 仅探测和公开数量统计 |
不存在 wordpress-com OAuth 导入源。WordPress.com 站点必须使用 WXR 导出,或兼容的 EmDash Exporter 连接。
导入 WXR 文件
当 WordPress 可以导出你所需的内容、且无法安装 EmDash Exporter 时,请使用 WXR。
-
在 WordPress 中打开 Tools → Export,选择所需内容,并下载 XML 文件。
-
在 EmDash 中,选择管理后台侧边栏中的 Import 并上传该文件。
-
在创建架构或内容之前,检查检测到的文章类型、字段、作者、分类法、可复用区块和附件 URL。
XML 包含附件元数据和来源 URL,不包含媒体的字节内容。在可选的媒体复制完成之前,请保持 WordPress 可访问。
连接 EmDash Exporter
当你控制该 WordPress 站点、并且需要草稿或受支持设置等需要认证的数据时,请使用导出器。评论、菜单、徽标、站点图标,以及用于生成迁移密钥的 Tools → EmDash Migration 页面,都需要导出器 1.2.0 或更高版本。任何版本的导出器都可以使用 WordPress 用户名和应用程序密码进行连接。导出器通过其 emdash/v1 API 端点发送数据;它不会授予 EmDash 对数据库的直接访问权限。
管理后台导入流程
管理后台依次执行以下阶段:
- 连接。 上传 WXR 文件、粘贴 EmDash Exporter 迁移密钥,或输入站点 URL。
- 分析。 读取文章类型、必填字段、作者、附件和架构兼容性。
- 审阅。 选择文章类型、集合映射、作者和受支持的附加项。
- 准备。 创建缺失的集合和字段。类型不兼容的现有字段会阻止该映射。
- 导入。 转换并创建内容。导出器路径对内容、评论和收尾阶段使用有大小限制的请求。
- 复制媒体。 将所选 WXR 附件下载到 EmDash 存储中,并重写匹配的 URL。
WXR 路径可以导入文章、页面、自定义文章类型、分类法、可复用区块、作者或访客 byline,以及导出文件中列出的媒体。导出器路径还可以从在线的 WordPress API 获取所选站点设置和受支持的 SEO 值;使用导出器 1.2.0 或更高版本时,还可以获取评论、菜单、徽标和站点图标。
理解分析结果
对于检测到的每个文章类型,审阅界面会显示建议的集合以及四种架构状态之一:
| 状态 | 含义 |
|---|---|
| Ready | 集合和必填字段已经具有兼容的类型 |
| New collection | 准备步骤将创建该集合及其必填字段 |
| Add fields | 集合已存在,准备步骤将添加缺失的字段 |
| Incompatible | 现有字段的类型不同;请在导入该文章类型之前修复映射或架构 |
准备步骤只做增量添加。它不会为了让导入适配而更改现有字段的类型。
状态映射
内容路由会保存 WordPress 导入中的两种状态:
| WordPress 状态 | EmDash 状态 |
|---|---|
publish | published |
draft | draft |
pending | draft |
private | draft |
future、trash 或其他值 | draft |
导入器不会保留 WordPress 中待审、私密、定时发布或回收站的语义。在 EmDash 中发布这些条目之前,请先检查它们。
内容与标识符
WXR 源和导出器源会将 Gutenberg 标记转换为 Portable Text。它们将 post 映射到 posts,将 page 映射到 pages,并将已知的自定义文章类型映射到集合 slug。WordPress 的内部文章类型会被排除。可复用区块(wp_block)会作为 EmDash 的 sections 处理,而不是普通条目。
对于一个导入的条目:
- 如果可用,WordPress 文章的 slug 会成为 EmDash 的 slug。
- EmDash 会生成自己的数据库 ID。
- 作者映射会关联一个 EmDash 用户。未映射的 WordPress 作者可以变成可复用的访客 byline。
- WordPress ID 仅被临时用于解析菜单、评论、特色图片和翻译等关系。它们不是用于检测现有 WXR 条目的持久标识。
使用 skipExisting 重新运行 WXR 时,会按集合、slug 和语言区域匹配现有条目。因此,slug 发生变化可能会创建另一个条目。导出器路径使用相同的 slug 与语言区域检查,并根据其跳过的条目重建 WordPress ID 关系映射。
媒体复制与去重
媒体阶段会下载每个附件 URL,计算已下载字节内容的 SHA-1 哈希,并查找具有该内容哈希的现有媒体行。即使 WordPress URL 不同,字节完全相同的内容也会复用现有的媒体记录。
哈希以 sha1: 前缀存储。它是去重键,而不是安全签名。两个 URL 不会仅仅因为文件名相同而被视为重复。
复制媒体之后,导入器会重写 Portable Text、文本、字符串、图片和文件字段中匹配的 URL。在验证下载和重写后的页面之前,请保持 WordPress 来源在线。
重试行为
管理后台不会为 WXR 导入保存持久的恢复令牌。如果某个请求失败:
- 在启用 skip existing 的情况下重新运行分析和导入。
- 现有条目会按集合、slug 和语言区域被跳过。
- 对于已经存储的文件,重新运行媒体步骤是安全的,因为字节完全相同的下载会复用内容哈希。
- 重试之前,请检查部分完成的架构更改以及 slug 发生变化的条目。
导出器流程被分块处理,以适应 Worker 的限制。浏览器在请求之间携带游标以及 WordPress 到 EmDash 的关系映射。如果浏览器丢失了该状态,请重新开始导入;被跳过的条目会在处理内容页面时重建关系映射。
独立的 emdash import wordpress CLI 会将转换后的 JSON 文件写入输出目录。它的 --resume 选项会读取 .wp-migration-progress.json,并跳过其中已记录的 WordPress 文章和附件 ID。这个文件转换工作流不是管理后台的数据库导入,也不会让管理后台的请求变得可恢复。
管理后台 API 契约
这些端点为需要认证的管理后台页面提供支持。它们需要具有 import:execute 权限的管理员会话,以及 X-EmDash-Request: 1 请求头。成功响应通常使用 { "success": true, "data": ... } 信封;错误使用 { "success": false, "error": { "code", "message" } }。
探测 URL
POST /_emdash/api/import/probe 接受 JSON { "url": "https://example.com" }。
它的 data 值是 { success: true, result }。result 包含 url、isWordPress、bestMatch 和 allMatches。仅匹配到普通的 WordPress REST 时,会建议上传 WXR;它不会启用直接的 REST 导入。
分析 WXR 文件
POST /_emdash/api/import/wordpress/analyze 接受带有 file 部分的 multipart/form-data。它的 data 值包含站点、文章类型分析、附件摘要、作者摘要、分类法数量以及自定义字段建议。
准备架构
POST /_emdash/api/import/wordpress/prepare 接受如下 JSON 结构:
{
"postTypes": [
{
"name": "post",
"collection": "posts",
"fields": [
{
"slug": "title",
"label": "Title",
"type": "string",
"required": true,
"searchable": true
}
]
}
]
}
它的 data 值包含 success、collectionsCreated、fieldsCreated 以及每个集合的 errors。
执行 WXR 导入
POST /_emdash/api/import/wordpress/execute 接受包含以下部分的 multipart/form-data:
file:WXR 文件。config:一个 JSON 字符串,包含postTypeMappings、skipExisting、可选的authorMappings、可选的importSections,以及可选的整个导入范围的locale。
它的 data 值包含 success、imported、skipped、errors、byCollection,以及可选的 sections 和分类法摘要。
复制媒体
POST /_emdash/api/import/wordpress/media 接受 JSON { "attachments": [...], "stream": true }。默认启用流式传输。流式响应是以换行分隔的 JSON,先是 progress 记录,最后是一条 result 记录;它不使用常规的 API 信封。将 stream 设置为 false,即可收到包裹着 { imported, failed, urlMap } 的常规信封。
重写媒体 URL
POST /_emdash/api/import/wordpress/rewrite-urls 接受 JSON { "urlMap": { "old": "new" }, "collections": ["posts"] }。可选的集合列表用于限制重写范围。它的 data 值包含已更新的条目数量和已重写的 URL 数量,以及错误信息。
使用导出器 API
POST /_emdash/api/import/wordpress-plugin/analyze 接受 JSON { "url", "token" },其中 token 是 WordPress 用户和应用程序密码的 Base64 基本认证值。它的 data 值是 { success: true, analysis }。
POST /_emdash/api/import/wordpress-plugin/execute 接受包含 url、token 和 config 的 JSON。管理后台还会提供 phase(content、comments 或 finalize)。每个响应包含 done、可选的下一个 cursor、部分 result,以及一个 chunk 对象,其中带有任何更新后的 idMap、translationGroups 或 commentRoots。管理后台会合并 chunk 中的值,并在下一个请求中发送累积的映射。
故障排除
检测到站点但无法直接导入
wordpress-rest 结果只是一次探测。请上传 WXR 文件,或安装 EmDash Exporter 后再次探测该站点。
文章类型不兼容
在审阅界面中展开该文章类型,找到冲突的字段。更改目标集合,或在 Content Types 中调和该字段。导入器不会替换现有字段的类型。
部分媒体失败
最终的媒体结果会列出失败的来源 URL。请确认每个 URL 是公开的、仍然存在,并且不会重定向到私有网络地址。修复访问问题后重试媒体步骤;已完成的、字节完全相同的文件会被复用。
下一步
- 操作流程请参见从 WordPress 迁移。
- 内容导入完成后,请参见移植 WordPress 主题。
- 当站点依赖自定义行为时,请参见移植 WordPress 插件。