从typecho迁移到astro,记录下迁移过程
前言
我的博客已经建立五年多了,自始至终,它都建立在 Typecho 之上。作为一款经典的 PHP 博客系统,Typecho 以其轻量化、高效率、响应快的核心优势,完美契合了我起步时的需求。随着时间推移与技术环境的演进,最终促使我做出了迁移的决定。Typecho 的优点依然存在,但其局限性也日益明显:
1.审美与体验的滞后:其后台与管理界面,用高情商的话说是“简洁朴素”,但坦率讲,多年来几乎未有现代化的改进,用起来已显得有些过时。
2.缓慢的维护节奏:项目更新频率极低,修复问题和适配新环境的步伐迟缓,让人感觉核心团队近乎处于放弃状态。
3.核心体验的不足:文章编辑界面功能简陋,体验并不流畅。
正是这些来自实际体验的痛点,共同将我引向了Astro,再见typecho,你好astro。接下来记录下如何将typecho的数据迁移到astro。
一、导出typecho文章
这里我用的是这个插件,导出 Typecho 内容至 Markdown 文件
开源地址:https://github.com/ShiinaKin/Typecho-Plugin-Tp2MD
下载最新的版本,解压并上传到Typecho的Typecho/usr/plugins目录,解压后文件夹重命名为 Tp2MD,上传至插件目录并启用。
我的文章不多,手动导入的。在post文件夹下新建文章名.md,然后把从typecho转的markdown格式的内容复制粘贴进去就行。
二、迁移typecho评论
我用的是waline评论系统,这里顺便说下怎么docker compose自建waline评论系统,在/opt/waline新建docker-compose.yml文件,改下内容,然后执行docker compose up -d
version: '3'services: waline: container_name: waline image: lizheming/waline:latest restart: always ports: - 8360:8360 #默认映射 `8360:8360`,可根据需要调整主机端口(例如 `3000:8360`)。 volumes: - ${PWD}/data:/app/data # `${PWD}/data` 表示当前目录下的 `data` 文件夹,映射到容器内的 `/app/data` environment: TZ: 'Asia/Shanghai' # 时区 # SQLite 数据库配置 SQLITE_PATH: '/app/data' # 指定 SQLite 数据库文件路径。 JWT_TOKEN: '' # 用于 API 认证,务必设置为复杂值 # 站点基础配置 SITE_NAME: '' # 替换为你的博客名称 SITE_URL: '' # 替换为你的博客 URL SECURE_DOMAINS: '' # 替换为你的域名 # 站长邮箱 AUTHOR_EMAIL: '' # 替换为你的邮箱 # SMTP 服务配置(可选,配置邮件通知,需根据你的邮箱服务商调整(例如 163、Gmail))博主未使用 SMTP_SERVICE: '' # SMTP 服务商,可选其他(如 Gmail) SMTP_USER: '' # 发件邮箱 SMTP_PASS: '' # SMTP 密码或授权码 # 安全配置(可选)博主未使用 IPQPS: '80' # 单 IP 评论频率限制 COMMENT_AUDIT: 'true' # 是否需要审核评论 #AKISMET_KEY: 'ea271a30b695' # 反垃圾评论 Key(可选,需在 akismet.com 申请)这里注意下,请保证新链接结构和旧链接结构一致,比如https://www.weirain.com/index.php/archives/330/ 文章下的评论同步到 https://www.weirain.com/posts/330/ 然后将下面的代码保存为 php 文件上传到网站根目录,然后访问保存为json文件即可。脚本内容可根据自己的情况修改。登录waline后台导入评论。
<?php/** * Typecho -> Waline 终极 ISO 时间修复版 * 1. 路径修正:/posts/123 和 /guestbook/ * 2. 时间修正:使用 ISO 8601 标准格式 (2020-12-20T13:03:17.000Z) * 这是 Node.js 后端唯一能 100% 识别的字符串格式 */
header('Content-Type: application/json; charset=utf-8');
// --- 数据库配置 ---$db_host = '';$db_user = '';$db_pass = '';$db_name = '';$prefix = '';$port = '3306';
try { $dsn = "mysql:host=$db_host;port=$port;dbname=$db_name;charset=utf8mb4"; $pdo = new PDO($dsn, $db_user, $db_pass); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$sql = "SELECT c.cid, c.author, c.mail, c.url, c.text, c.ip, c.agent, c.created, co.cid as article_id, co.slug FROM {$prefix}comments c LEFT JOIN {$prefix}contents co ON c.cid = co.cid WHERE c.type = 'comment' AND c.status = 'approved'";
$stmt = $pdo->query($sql); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
$comments_data = [];
foreach ($rows as $row) {
// 1. 路径处理 $article_path = '/posts/' . $row['article_id']; if ($row['slug'] == 'messages' || $row['slug'] == 'guestbook') { $article_path = '/guestbook/'; }
// 2. 【核心修复】使用 ISO 8601 格式 // 之前失败是因为中间有空格,Node.js 解析不出来 // 现在改成:2020-12-20T13:03:17.000Z $iso_date = gmdate('Y-m-d\TH:i:s.000\Z', $row['created']);
$comments_data[] = [ 'nick' => $row['author'], 'mail' => $row['mail'], 'link' => $row['url'], 'comment' => $row['text'], 'ip' => $row['ip'], 'ua' => $row['agent'], 'url' => $article_path, 'status' => 'approved',
// 3. 全方位覆盖时间字段 'createdAt' => $iso_date, 'updatedAt' => $iso_date, 'insertedAt'=> $iso_date, // 连插入时间也伪造了,防止它用当前时间
'like' => 0 ]; }
$native_export = [ 'type' => 'waline', 'version' => 1, 'time' => time() * 1000, 'tables' => ['Comment'], 'data' => [ 'Comment' => $comments_data ] ];
echo json_encode($native_export, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
} catch (Exception $e) { echo json_encode(['error' => $e->getMessage()]);}?>结尾
至此,从 Typecho 到 Astro 的完整迁移之旅便告一段落。回顾整个过程,实话实说,总共花费了我一天多的时间,这远比新建一个站点要来得折腾。
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
风尘落微雨