wjs-converting-wp-to-hugolisted
Install: claude install-skill jianshuo/claude-skills
# wjs-converting-wp-to-hugo
把任意 WordPress 站迁成 **Hugo + Markdown + git** 静态站,部署到 **GitHub Pages**。
输入只需两样,**全程离线、零第三方依赖**:
1. **WXR 导出** — WordPress 后台 `工具 → 导出 → 所有内容` 得到的 `*.xml`(包含全部文章/页面/分类/标签的 HTML 正文)。
2. **`uploads/` 文件夹** — 站点的 `wp-content/uploads/`(按 `年/月` 分目录的图片与附件)。
产出:`content/*.md` + `static/wp-content/uploads/` + 手写极简主题,Hugo 构建,GitHub Actions 发布。
**全站 URL 保持 `/archives/<数字>/` 不变,老链接 100% 不断。**
## When to use
- 用户有一个 WordPress 站,想去掉动态/评论/数据库,改成 git + Markdown 维护。
- 用户提供了 WXR `.xml` 和 `uploads/`(或能拿到)。
- 老链接必须保留(SEO / 外部引用)。
## When NOT to use
- 没有 WXR,只有线上站 → 先在 WP 后台导出,或用 REST API 拉 JSON(本 skill 走 WXR,更可移植)。
- 要保留评论/会员/搜索等动态功能 → 静态站做不了,不适用。
- 站点极小(几篇)→ 手抄更快。
## Core principle
**WXR 是唯一真相源,`uploads/` 直接当静态资源。**
图片不下载、不改名:把 `uploads/` 拷进 `static/wp-content/uploads/`,正文里的图片 URL 改成 **根相对** `/wp-content/uploads/...` 即可原地解析。文章 URL 从 `<link>` 原样保留。转换器是**纯函数 + 单元测试**,先测后写。
## Pipeline
```
WXR .xml + uploads/ → wxr_to_hugo.py → content/*.md + static/wp-content/uploads/ → hugo build → GitHub Actions → Pages
```
## Two decisions you MUST ask the user (do not silently decide)
WordPress 里有两类内容静态站处理不了,**必须问用户**,别擅自发布:
1. **密码保护文章**(`<wp:post_password>` 非空)。静态站无密码门 → 发布就是公开。
选项:**排除**(默认,最安全,URL 会 404)/ 公开发布 / 转成 `draft`。
**核对计数务必用 ElementTree(即 `parse_items`),别用裸 grep**:`<wp:post_password>` 的值是 CDATA 包裹的(`<![CDATA[secret]]>`),`grep '<wp:post_password>[^<]*</...>'` 会把每条都当空 → 误报「0 篇密码文章」漏掉真有密码的文章(maggiacito.com 实战,差点漏发 1 篇)。
2. **WordPress 脚手架页**(`s