Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
8602512
cc
ruibaby Apr 17, 2026
9fb3767
cc
ruibaby Apr 17, 2026
33aae64
refactor: redesign attachment handler and data summary UI
ruibaby Apr 17, 2026
e06d7fc
feat: add migration hints to all provider import cards
ruibaby Apr 17, 2026
304aee6
refactor: merge hints into single alert and use full width
ruibaby Apr 17, 2026
1fcec1f
fix: import VAlert in WordPressMigrateDataParser
ruibaby Apr 17, 2026
9d94fa2
fix: align dashed lines in step navigation
ruibaby Apr 17, 2026
a2eaa38
style: unify step navigation active state with migrate page
ruibaby Apr 17, 2026
de89b89
style: unify Halo attachment handler UI with generic handler
ruibaby Apr 17, 2026
9820d4b
feat: move attachment upload to import time with content-aware replac…
ruibaby Apr 17, 2026
68ed8d4
feat: add video and audio support to attachment preprocessor
ruibaby Apr 17, 2026
7b1362d
feat: extend attachment preprocessor for Halo metadata fields
ruibaby Apr 17, 2026
b5b00ca
feat: add Halo plugin dependency checks before migration
ruibaby Apr 17, 2026
c0eeec9
style: unify Halo attachment handler UI with generic handler
ruibaby Apr 17, 2026
98b21d5
Add Copilot instructions
ruibaby Apr 17, 2026
85c1abd
refactor: streamline migrate provider runtime
ruibaby Apr 17, 2026
38e95aa
refactor: harden migrate runtime flow
ruibaby Apr 17, 2026
ad25757
feat: support ghost media migration
ruibaby Apr 17, 2026
1a8f65d
feat: support ghost gallery blocks
ruibaby Apr 17, 2026
daba8e3
Typecho: add error handling and attachment parsing
ruibaby Apr 17, 2026
f579bab
Sanitize WordPress HTML and normalize galleries
ruibaby Apr 18, 2026
12c3324
Resolve WP featured images; reorder providers
ruibaby Apr 18, 2026
21fcb18
feat: migrate source users and preserve ownership
ruibaby Apr 18, 2026
98de13d
Add Halo-specific parsing and ownership fallback
ruibaby Apr 18, 2026
421fa4c
feat: normalize wordpress media blocks
ruibaby Apr 18, 2026
3a96b37
feat: stabilize wordpress original media urls
ruibaby Apr 18, 2026
cc48dc9
refactor: align typecho attachments with shared flow
ruibaby Apr 18, 2026
91204da
fix: harden local attachment path matching
ruibaby Apr 18, 2026
ea70bb6
test: add migration logic unit coverage
ruibaby Apr 18, 2026
da9d3d9
refactor: unify provider import cards
ruibaby Apr 18, 2026
8cc5939
test: expand migration parser coverage
ruibaby Apr 18, 2026
5a7a12a
test: harden ghost parser coverage
ruibaby Apr 18, 2026
eaf2172
Replace Hugo provider with Markdown provider
ruibaby Apr 18, 2026
3419cd3
Support local attachment strategies & Markdown import
ruibaby Apr 18, 2026
a5982b6
Use filename for fallback slug; remove selection state
ruibaby Apr 18, 2026
504228b
Add provider fixtures and update parser tests
ruibaby Apr 18, 2026
1c1d2a2
Harden Typecho parser edge cases
ruibaby Apr 18, 2026
e8e996a
Improve Ghost data parser robustness
ruibaby Apr 18, 2026
b34b750
Harden WordPress media edge cases
ruibaby Apr 18, 2026
0df6ffa
Support markdown frontmatter cover
ruibaby Apr 18, 2026
5272c33
Refresh migration documentation
ruibaby Apr 19, 2026
f05afa5
Fix imported comment threading
ruibaby Apr 19, 2026
f427266
Add localized buttonText to migrate upload cards
ruibaby Apr 19, 2026
1bfedbc
Reorder RSS and Atom providers after Markdown
ruibaby Apr 19, 2026
78c68a8
Unify provider migration prompts
ruibaby Apr 19, 2026
7a777f2
Improve Halo migration UI and add docs link
ruibaby Apr 19, 2026
e232ac2
Stabilize markdown frontmatter test
ruibaby Apr 19, 2026
643b114
docs: update migration docs and provider guides
ruibaby Apr 19, 2026
5a60ee6
Update AtomMigrateDataParser.vue
ruibaby Apr 20, 2026
b1d9b41
Remove docs site and add provider doc+preview
ruibaby Apr 20, 2026
3ed6e71
Update MigrateTaskDashboard.vue
ruibaby Apr 20, 2026
d04aeb2
Remove unused files
ruibaby Apr 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Copilot Instructions

## Build, test, and lint commands

### Root project (Gradle / Java 21)

```bash
./gradlew build
./gradlew test
./gradlew test --tests "run.halo.migrate.SomeTest"
./gradlew haloServer
./gradlew pnpmInstall
```

- `./gradlew build` also builds `ui/` and copies the frontend bundle into `build/resources/main/console/`.
- `./gradlew haloServer` starts a Halo Docker environment with the plugin loaded.

### Frontend (`ui/`, pnpm / Node 24)

```bash
cd ui
pnpm install
pnpm build
pnpm dev
pnpm lint
pnpm prettier
pnpm type-check
```

## High-level architecture

- This repository is a Halo plugin with a **minimal Java backend** and a **browser-heavy Vue 3 frontend**. The root Gradle project packages the plugin; the `ui/` subproject contains the migration UI and most of the logic.
- The Java side is intentionally small: `MigratePlugin` is the plugin entry point, and `MigrationController` only exposes `POST /migrations/rss-parse` so the frontend can fetch remote RSS/Atom content without browser CORS issues.
- The frontend is registered through `ui/src/index.ts`, which adds the `/migrate` routes to Halo Console. The main user flow is:
1. `SelectProviderView.vue` lets the user choose a source platform.
2. A provider parser component in `ui/src/modules/<provider>/` reads export files and converts them into a shared `MigrateData` shape.
3. Attachment handling runs before import: most providers use `MigrateAttachmentHandler.vue`, Halo uses `HaloMigrateAttachmentHandler.vue`, and local media URL rewriting happens in `use-attachment-preprocessor.ts`.
4. `use-migrate-task.ts` turns `MigrateData` into `MigrateTaskGroup[]`, and `MigrateView.vue` executes those tasks with `fastq` at concurrency `9`.
- `use-migrate-task.ts` maps each migrated content type directly to Halo APIs: tags/categories/comments/attachments use generated core clients, post/page imports use console draft APIs, and plugin resources without generated clients (moments, photos, links) go through `axiosInstance`.

## Key conventions

- **UnoCSS compile-class mode is enabled.** Inline utility classes in Vue templates use the `:uno:` prefix, for example `class=":uno: flex items-center gap-2"`.
- **New migration providers are registered centrally.** Add the provider entry in `ui/src/modules/index.ts`, then implement its parser UI under `ui/src/modules/<provider>/`.
- **Provider parser components are write-only.** They should emit `update:data` with a `MigrateData` payload and expose `reset()` for `MigrateView.vue` to call. The shared extension docs in `docs/extend/provider.md` describe this contract.
- **Attachment handling is shared unless the provider is Typecho.** Most providers feed attachments through `MigrateAttachmentHandler.vue`; Typecho owns its own remote attachment migration flow inside `TypechoMigrateDataParser.vue`.
- **Attachment migration behavior depends on the selected strategy.** Local upload mode removes `LOCAL` attachments from the final attachment task list and rewrites referenced URLs after uploading files; manual mode only creates Halo attachment records with the selected storage policy.
- **Provider-specific attachment paths matter.** `providerItems` can set `options.attachmentFolderPath`; `use-migrate-task.ts` uses that to build local attachment annotations such as `migrate-from-1.x/...` and `migrate-from-wp/...`.
- **Keep API client usage consistent with existing code.**
- `coreApiClient`: tags, categories, comments, replies, attachments, menus, storage policies.
- `consoleApiClient`: draft post/page creation, current user lookup, plugin listing, console attachment upload.
- `axiosInstance`: moments, photos, and links endpoints that do not have generated client methods.
- **Do not change task queue concurrency casually.** Import execution in `MigrateView.vue` uses `fastq.promise(asyncWorker, 9)`, which is tuned for current Halo API behavior.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,4 @@ application-local.properties
/workplace/
node_modules
/docs/.vitepress/cache/
/src/main/resources/console/
/src/main/resources/console/
61 changes: 26 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,23 @@

支持从其他平台迁移数据到 Halo 的插件。

![Screenshot](./docs/img/screenshot.png)
![Screenshot](./images/preview.png)

目前已支持以下平台:

1. Halo 1.5 / 1.6
2. [WordPress](https://wordpress.org/)
3. RSS / Atom 订阅链接
4. [Hugo](https://gohugo.io/)
5. [Ghost](https://ghost.org/)
6. [Typecho](https://github.com/typecho/typecho)
2. WordPress
3. Ghost
4. Typecho
5. RSS / Atom 订阅文件或订阅链接
6. Markdown(适用于 Markdown + Front Matter 静态博客内容导入)

## 功能概览

1. 每个 Provider 拥有独立的导入 UI 和数据转换逻辑,最终统一汇总为 Halo 导入任务。
2. 大多数平台支持统一的附件处理流程:本地上传或手动迁移;Markdown 仅支持本地目录上传;RSS / Atom 会保留原始远程资源链接。
3. 对包含邮箱的来源用户,导入时会优先匹配现有 Halo 用户;若不存在,则自动创建 `guest` 用户,并尽量保留文章、页面、评论的归属关系。
4. Markdown 导入支持 YAML / TOML / JSON Front Matter,支持常见标题、摘要、分类、标签、发布时间、页面类型以及 `cover` / `thumbnail` / `feature_image` 等封面字段。

## 使用方式

Expand All @@ -21,8 +28,18 @@
2. 安装,插件安装和更新方式可参考:<https://docs.halo.run/user-guide/plugins>
3. 启动插件之后,即可在 Console 的左侧菜单栏看到 **迁移** 的菜单。

> **Warning**
> 详细的迁移文档请查阅 <https://halo-plugin-migrate.pages.dev>
> [!NOTE]
> 详细的迁移文档请查阅 <https://www.halo.run/docs/plugin-migrate>

> [!TIP]
> 建议先在本地环境测试导入,确认无误后再考虑在生产环境执行。这样做的原因是:
> 1. 导入失败的因素较多,在本地更容易快速重试并定位原因。
> 2. 导入过程会频繁请求后端并上传附件,在线上环境可能因为服务器性能或网络波动导致导入变慢,甚至出现部分数据导入失败。
> 3. 本地验证通过后,可以利用 Halo 自身的备份恢复能力,更快地在生产环境完成数据恢复或回滚。

## 添加迁移平台

如果你想为此插件添加一个迁移平台,请查阅:[扩展一个新的迁移平台](./docs/provider.md)

## 开发环境

Expand All @@ -49,7 +66,7 @@ git clone git@github.com:{your_github_id}/plugin-migrate.git
cd path/to/plugin-migrate
```

### 运行方式 1(推荐)
### 运行方式(推荐)

> 此方式需要本地安装 Docker

Expand All @@ -70,29 +87,3 @@ cd path/to/plugin-migrate
```

执行此命令后,会自动创建一个 Halo 的 Docker 容器并加载当前的插件,更多文档可查阅:<https://docs.halo.run/developer-guide/plugin/basics/devtools>

### 运行方式 2

> 此方式需要使用源码运行 Halo

编译插件:

```bash
# macOS / Linux
./gradlew build

# Windows
./gradlew.bat build
```

修改 Halo 配置文件:

```yaml
halo:
plugin:
runtime-mode: development
fixedPluginPath:
- "/path/to/plugin-migrate"
```

最后重启 Halo 项目即可。
49 changes: 0 additions & 49 deletions docs/.vitepress/config.mts

This file was deleted.

13 changes: 0 additions & 13 deletions docs/.vitepress/theme/custom.css

This file was deleted.

23 changes: 0 additions & 23 deletions docs/.vitepress/theme/index.ts

This file was deleted.

86 changes: 0 additions & 86 deletions docs/extend/provider.md

This file was deleted.

49 changes: 0 additions & 49 deletions docs/extend/steps.md

This file was deleted.

Binary file removed docs/img/ghost-1.png
Binary file not shown.
Binary file removed docs/img/ghost-2.png
Binary file not shown.
Binary file removed docs/img/ghost-3.png
Binary file not shown.
Binary file removed docs/img/ghost-4.png
Binary file not shown.
Binary file removed docs/img/halo-provider-data-export.png
Binary file not shown.
Binary file removed docs/img/halo-provider-migrate-plugin.png
Binary file not shown.
Binary file removed docs/img/screenshot.png
Binary file not shown.
Loading