从 WordPress 迁移

本页内容

EmDash 提供从 WordPress 的完整迁移路径。无需 CLI,在管理后台即可导入文章、页面、媒体和分类法。

开始之前

导出内容

在 WordPress 中打开 工具 → 导出,下载完整导出文件(.xml)。

备份站点

在确认迁移成功之前,请保持 WordPress 站点在线运行。

导入方式

EmDash 支持三种导入 WordPress 内容的方式:

方式适用场景包含草稿需要认证
WXR 文件上传完整迁移
WordPress.com托管在 WordPress.com 的站点OAuth
REST API(探测)在导出前查看内容概况可选

大多数迁移建议使用 WXR 文件上传,可覆盖草稿、自定义字段和私密文章等全部内容。

WXR 文件导入

  1. 从 WordPress 导出

    在 WordPress 后台:工具 → 导出 → 所有内容 → 下载导出文件

  2. 打开导入向导

    在 EmDash 中:管理 → 设置 → 导入 → WordPress

  3. 上传导出文件

    拖放 .xml 或点击浏览。文件在浏览器中解析。

  4. 查看检测到的内容

    向导会显示类似信息:

    Found in export:
    ├── Posts: 127 → posts [New collection]
    ├── Pages: 12  → pages [Add fields]
    └── Media: 89 attachments
  5. 配置映射

    选择要导入的文章类型。EmDash 会:

    • 为未映射的文章类型自动新建集合(collection)
    • 向已有集合补充缺失字段
    • 对字段类型冲突发出警告
  6. 执行导入

    点击 导入内容,可看到每个条目的处理进度。

  7. 导入媒体(可选)

    内容导入完成后,可选择是否下载媒体文件。EmDash 会:

    • 从 WordPress URL 下载
    • 按内容哈希去重
    • 自动重写内容中的 URL

内容转换

Gutenberg 到 Portable Text

EmDash 将 Gutenberg 块转换为 Portable Text 结构化格式。

Gutenberg 块Portable Text说明
core/paragraphblock style=“normal”保留行内标记
core/headingblock style=“h1-h6”级别来自块属性
core/imageimage更新媒体引用
core/listlistItem 类型的 block有序与无序列表
core/quoteblock style=“blockquote”含引用信息
core/codecode保留语言属性
core/embedembed保存 URL 与提供商
core/gallerygallery图片引用数组
core/columnscolumns保留嵌套内容
未知块htmlBlock保留原始 HTML 供复查

未知块以 htmlBlock 存储,附带原始 HTML 与块元数据。可手动处理或编写自定义 Portable Text 组件渲染。

经典编辑器内容

经典编辑器的 HTML 会转为 Portable Text 块。行内样式(<strong><em><a>)变为 span 上的标记。

状态映射

WordPress 状态EmDash 状态
publishpublished
draftdraft
pendingpending
privateprivate
futurescheduled
trasharchived

分类法导入

分类与标签作为分类法导入,层级关系保留:

WordPress:                    EmDash:
├── Categories (hierarchical) ├── taxonomies table
│   ├── News                  │   ├── category/news
│   │   ├── Local             │   ├── category/local (parent: news)
│   │   └── World             │   ├── category/world (parent: news)
│   └── Sports                │   └── category/sports
└── Tags (flat)               └── content_taxonomies junction
    ├── featured                  ├── tag/featured
    └── breaking                  └── tag/breaking

自定义字段与 ACF

文章元数据与 ACF 字段在导入时会被分析:

  1. 分析阶段

    向导会检测自定义字段并建议 EmDash 字段类型:

    Custom Fields:
    ├── subtitle (string, 45 posts)
    ├── _yoast_wpseo_title → seo.title (string, 127 posts)
    ├── _thumbnail_id → featuredImage (reference, 89 posts)
    └── price (number, 23 posts)
  2. 字段映射

    _edit__wp_ 开头的内部字段默认隐藏。SEO 插件字段映射到 seo 对象。

  3. 类型推断

    EmDash 根据值推断类型:

    • 数字字符串 → number
    • "1""0""true""false"boolean
    • ISO 日期 → date
    • 序列化的 PHP/JSON → json
    • WordPress ID(如 _thumbnail_id)→ reference

URL 重定向

导入后 EmDash 会生成重定向映射:

{
	"redirects": [
		{ "from": "/?p=123", "to": "/posts/hello-world" },
		{ "from": "/2024/01/hello-world/", "to": "/posts/hello-world" },
		{ "from": "/category/news/", "to": "/categories/news" }
	],
	"feeds": [
		{ "from": "/feed/", "to": "/rss.xml" },
		{ "from": "/feed/atom/", "to": "/atom.xml" }
	]
}

可应用到:

  • Cloudflare 重定向规则
  • 主机平台的重定向配置
  • astro.config.mjs 中 Astro 的 redirects 选项

概念对照表

将 WordPress 习惯映射到 EmDash 时可参考下表:

WordPressEmDash说明
register_post_type()管理后台中的集合通过控制台或 API 创建
register_taxonomy()分类法或数组字段视复杂度而定
register_meta()集合 schema 中的字段有类型,非任意键值
WP_QuerygetCollection(filters)运行时查询
get_post()getEntry(collection, id)返回条目或 null
wp_insert_post()POST /_emdash/api/content/{type}REST API
the_content<PortableText value={...} />Portable Text 渲染
add_shortcode()Portable Text 自定义块自定义渲染组件
register_block_type()Portable Text 自定义块与短代码类似
add_menu_page()插件管理页位于 /_emdash/admin/
add_action/filter()插件钩子hooks.content:beforeSave
wp_optionsctx.kv键值存储
wp_postmeta集合字段结构化存储
$wpdbctx.storage直接访问存储层
分类/标签分类法保留层级

API 导入(进阶)

WordPress 导入可通过管理后台与 REST API 使用。为获得字段映射、冲突处理和进度跟踪,建议使用导入向导。

程序化访问使用 /_emdash/api/import/wordpress/ 下的端点。

故障排除

「XML parsing error」

导出文件可能损坏或不完整,请从 WordPress 重新导出。

媒体下载失败

部分图片可能需要登录或 URL 已变更。导入会继续,失败 URL 会记录日志。

字段类型冲突

若已有集合中存在不兼容类型的字段,向导会提示冲突。可以:

  • 重命名 EmDash 中的字段
  • 调整 WordPress 字段映射
  • 删除并重建该集合

超大导出

超过约 100MB 时建议:

  1. 在 WordPress 中按文章类型分别导出
  2. 按顺序逐个导入文件
  3. 使用带 --resume 的 CLI 提高可靠性

下一步