使用 EmDash 管理后台分析 WordPress 站点、准备兼容的集合、导入内容、复制媒体并重写 URL。在导入后的站点通过验证之前,请保持 WordPress 站点可用。
开始之前
请准备以下内容:
- WordPress 数据库和
wp-content/uploads的备份。 - 一个已配置存储的 EmDash 站点(如果你打算复制媒体)。
- 一个 EmDash 管理员账户。WordPress 导入需要
import:execute权限。 - 一份完整的 WordPress eXtended RSS(WXR)导出文件,或者在 WordPress 站点上安装 EmDash Exporter 插件。
请记录当前的固定链接结构、规范来源(canonical origin)、重定向、菜单、启用的文章类型、分类法,以及新站点必须保留的所有由插件拥有的字段。
选择导入方法
| 方法 | 适用场景 | 包含的数据 |
|---|---|---|
| WXR 上传 | 你可以从 Tools → Export 导出 | 导出文件中包含的数据,包括文章、页面、自定义文章类型、分类法术语、可复用区块、作者和附件 URL |
| EmDash Exporter | 你控制该 WordPress 站点,并且可以安装 exporter | 需认证才能获取的内容,以及受支持的评论、菜单、站点设置、SEO 字段、分类法和媒体元数据 |
在没有 exporter 的情况下输入站点 URL,只会探测公开的 WordPress REST API。该探测可以检测到 WordPress,并统计公开的文章、页面和媒体数量,但无法执行直接的 REST 导入。
导出 WXR 文件
在 WordPress 中打开 Tools → Export,选择 All content,然后下载 XML 导出文件。WXR 文件指向 WordPress 来源上的媒体;它不包含附件的字节内容。
连接 EmDash Exporter
在 WordPress 中打开 Tools → EmDash Migration 并生成迁移密钥。把密钥粘贴到 EmDash 导入页面中。
你也可以输入 WordPress 站点 URL。检测到 exporter 后,通过 WordPress 应用密码界面授权 EmDash。在本地 HTTP 开发站点上,由于授权回调需要 HTTPS,请手动输入 WordPress 用户名和应用密码。
通过管理后台导入
-
在 EmDash 侧边栏中打开 Import WordPress,或访问
/_emdash/admin/import/wordpress。 -
上传 WXR 文件、粘贴 exporter 迁移密钥,或输入 WordPress URL。
-
查看分析结果。对每种 WordPress 文章类型,确认目标集合、必填字段,以及与现有字段的兼容性。
-
将 WordPress 作者映射到 EmDash 用户。未映射的源作者可以用访客 byline 表示,因此展示署名不依赖于授予 EmDash 登录权限。
-
对于 exporter 导入,选择是否导入菜单、站点标题和标语、logo 和 favicon,以及受支持的 SEO 值。这些开关不属于 WXR 路径。
-
开始导入。EmDash 会在创建条目之前,先创建缺失的兼容集合和字段。
-
如果发现了附件,请运行媒体步骤。EmDash 会下载源字节内容,通过已配置的存储适配器存储它们,并重写匹配的内容 URL。
转换行为
状态
导入器按如下方式映射 WordPress 状态:
| WordPress | EmDash |
|---|---|
publish | published |
draft | draft |
pending | draft |
private | draft |
future、trash 或未知状态 | draft |
计划发布的日期和 WordPress 的可见性规则不会根据这些状态重建。发布之前请检查每一篇导入的草稿。
富文本和可复用区块
Gutenberg 标记会被转换为 Portable Text。经典 HTML 由同一个转换器处理。请在渲染后的 EmDash 站点中检查复杂区块、嵌入内容、短代码、页面构建器标记和插件定义的区块。
WXR 中的 wp_block 条目会作为 sections 导入。它们不会被导入到普通的内容集合中。
集合和字段
默认的文章类型映射包括 post 到 posts,以及 page 到 pages。自定义文章类型使用经过清理的集合 slug。准备步骤会添加分析所需的标准标题、Portable Text 内容、摘要和特色图片字段。
类型兼容的现有字段会被复用。类型不匹配会阻止该集合的映射;导入器不会把现有字段强制转换为其他类型。
自定义字段和 SEO 数据
WXR 分析会报告非内部的 post-meta 键,并建议字段名称和类型,但 WXR 数据库导入写入的是标准的导入字段,而不是复制每一个任意的 meta 键。请把分析结果当作清单,其中列出的字段可能需要单独转换。
当目标集合有匹配的字段时,EmDash Exporter 路径可以复制自定义 meta 和 Advanced Custom Fields(ACF)的值。启用相应的导入开关后,它还可以创建并填充受支持的特色图片字段以及 Yoast 或 Rank Math 的 SEO 字段。请检查序列化的 PHP 值、重复器、灵活内容和插件特有的结构,而不要假定它们在 WordPress 中的表示与 EmDash 字段类型相匹配。
作者和 byline
被映射的 WordPress 作者会成为条目所有者。展示署名使用 byline。如果不存在用户映射,EmDash 会根据 WordPress 作者身份创建或复用访客 byline。
分类法
分类和标签会被导入到匹配的 EmDash 分类法定义中。exporter 路径可以为自定义分类法创建定义。没有匹配 EmDash 定义的 WXR 自定义分类法会被报告为缺失,其指派会被跳过。
媒体
媒体去重比较的是已下载字节内容的 SHA-1 哈希。具有相同哈希的现有媒体行会被复用。文件名和 WordPress ID 不是去重的键。
在 EmDash 下载附件期间,源站点必须保持可访问。来自附件 URL 的重定向在被跟随之前会先经过验证。
重试部分完成的导入
管理后台导入被设计为会跳过已有条目,但其匹配边界很重要:
- 现有内容按集合、slug 和语言区域匹配,而不是按 WordPress ID 匹配。
- 如果两次尝试之间源 slug 发生了变化,请检查两个条目并手动解决重复问题。
- 重新运行媒体步骤时,会按内容哈希复用已存储的字节相同的文件。
- exporter 流程发送有界的数据块。重新启动浏览器流程会重新运行内容页面,并根据被跳过的条目重建关系映射。
管理后台不会持久化 WXR 恢复文件。emdash import wordpress 上的 --resume 标志属于另一个 CLI 工作流,该工作流会把转换后的 JSON 文件写入磁盘;它不会恢复管理后台的数据库导入。
切换上线前的验证
对照源站点检查导入后的站点:
- 按文章类型和状态统计条目数量。
- 打开具有代表性的 Gutenberg、经典编辑器、短代码和页面构建器内容。
- 确认特色图片和内嵌媒体能从 EmDash URL 解析。
- 检查作者、byline、分类、标签、自定义分类法和翻译。
- 如果通过 exporter 导入,请测试菜单、评论、站点身份和 SEO 字段。
- 抓取旧的公开 URL,并为每一个发生变化的路由准备重定向。
- 验证草稿对未登录的访客仍然不可访问。
在新站点已在生产环境中成功运行、且不再需要回滚之前,请保留备份和 WordPress 部署。
故障排除
无法解析 XML 文件
请从 Tools → Export 重新导出文件,并确认下载已完成。不要用会改变编码的工具编辑 XML。
集合被标记为不兼容
现有字段的 slug 相同,但类型不同。请在重试之前更改文章类型的映射,或在 Content Types 下调和该字段。准备步骤会添加缺失的字段,但不会更改现有字段的类型。
媒体 URL 下载失败
请检查源附件是否无需 WordPress 会话即可访问。需要认证才能访问的媒体、已删除的文件,以及指向私有网络地址的重定向都会单独失败,并保留在媒体错误列表中。
适配主题
归档路由使用 getEmDashCollection(),slug 路由使用 getEmDashEntry()。entry.id 是路由标识符,通常就是 slug;entry.data.id 是关系辅助函数使用的已存储内容 ID。
下面的路由会渲染一篇导入的文章:
---
import { decodeSlug, getEmDashEntry } from "emdash";
import { PortableText } from "emdash/ui";
const slug = decodeSlug(Astro.params.slug);
if (!slug) return Astro.rewrite("/404");
const { entry: post, error } = await getEmDashEntry("posts", slug);
if (error) return new Response("Could not load the post", { status: 500 });
if (!post) return Astro.rewrite("/404");
---
<article>
<h1>{post.data.title}</h1>
<PortableText value={post.data.content} />
</article>
路由和组件的映射请阅读移植 WordPress 主题。端点契约和确切的重试边界请阅读内容导入。