AI摘要:本文介绍了Typecho1.3.0修复适配Joe主题(原版和再续前缘)的教程,包括头像问题、独立页面链接、后台CSS显示异常、搜索关键词显示问题等修复方法,并提供了相关补丁文件下载链接。
前言
Typecho1.3.0 在 2026 年 1 月 20 日发布,在发布后没多久就有许多的站长前往 Typecho 后台进行更新升级。他们更新后发现网站出现许多问题,Joe 原版主题与最新版的 Typecho1.3.0 有一些不兼容,本文章将给出 Joe 原版主题的修复适配 Typecho1.3.0 的教程,希望对你们有所帮助。
修补记录
1、头像问题
Typecho 默认使用的是 Gravata 头像,Gravatar 大多数的链接在国内都被墙了,加载失败不说,还影响博客加载速度。一般修改有两种方式,一种直接改主题,另一种改 typecho 的源码,我这里是直接改源码,当然修改的 cravatar 链接是一样的
打开:/typecho/var/Typecho/common.php,找到 gravatarUrl(大概 856 行) 如图所示
之前一直用 cn,挺好的,最近发现 cn 的 ssl 过期了,短时间内似乎未更换,后来发现 com 也可以用,直接就切换过来了
改为这个:
$url = $isSecure ? 'https://cravatar.com' : 'https://cravatar.cn';另外在推荐一个,也比较稳定:https://cravatar.com/
2、独立页面的链接无法正常生成或获取;侧边栏“随机文章”小工具中,文章条目的链接异常。
升级到 1.3 之后发现,独立页所有的链接统一指向主页,都失效了。
核心原因:Typecho 核心版本的升级可能引入了新的函数或更改了某些函数的调用方式,导致旧版主题中部分兼容代码失效。修复的重点在于更新主题中生成链接的相关代码,确保其与新版 Typecho 兼容。
涉及文件:
usr/themes/Joe/public/header.php:此文件通常包含网站的头部信息,独立页面的链接生成可能与此相关。
usr/themes/Joe/core/function.php:这是主题的功能函数文件,常用于扩展主题功能,"随机文章"这类小工具的逻辑很可能定义于此。
解决办法:下载这里提供的两个修正过的文件替换原文件即可:
下载地址(回复可见):
3、后台 css 显示异常

解决办法:定位到usr/themes/Joe/assets/typecho/config/css/joe.config.min.css文件,将其修改成这样即可,如图所示:
将开头的.col-mb-12.col-tb-8.col-tb-offset-2类名内容替换为.col-mb-12.col-tb-8.col-tb-offset-2{margin-left: 0;width: 100%;max-width: 100%;}其余内容不要动!
替换完成之后保存然后 ctrl+f5 刷新网页,就可以看到后台生效了。
4、搜索时不会出现搜索关键词的修复
问题截图:
找到主题文件夹所在位置,编辑joe/archive.php文件,大概在 25 行左右可以看到他取值为_keywords,把这个值改成archiveTitle即可解决问题

5、Joe 再续前缘主题适配与修复
最近把 Typecho 从 1.2.1 升级到了 1.3.0。由于 1.3.0 在路由机制和底层数据结构上做了一些调整,导致目前 Joe 再续前缘(joe-master/joe 再续前缘) 主题会出现首页 500 Server error、登录注册失效以及前端报错等问题。
路径:usr/themes/joe-master/public/common.php
目标:兼容 1.3 下不同伪静态/路径来源导致的路由判断问题,并补齐 ?user=login/register/retrieve 登录入口。
关键改动示例:
1:新增路径归一化,并从多来源获取 path(含剥离 /index.php 前缀):
$normalize_path = function ($path) {
if (!is_string($path) || $path === '') return '';
$path = explode('?', $path, 2)[0];
if ($path === '') $path = '/';
if ($path[0] !== '/') $path = '/' . $path;
if (str_starts_with($path, '/index.php')) $path = substr($path, strlen('/index.php'));
if ($path === '') $path = '/';
return $path;
};
$path_list = [];
$path_list[] = $normalize_path($self->request->getPathInfo());
$path_list[] = $normalize_path($self->request->getRequestUri());
foreach (['REQUEST_URI', 'PATH_INFO', 'ORIG_PATH_INFO', 'REDIRECT_URL', 'REDIRECT_URI'] as $k) {
$path_list[] = $normalize_path($_SERVER[$k] ?? '');
}
$path_list = array_values(array_unique(array_filter($path_list, function ($v) {
return $v !== '';
})));2:新增 ?user=login 等 Query 入口(兼容 1.3):
if (Helper::options()->JUser_Switch == 'on') {
$user_action = $_GET['user'] ?? null;
if (is_string($user_action)) {
if ($user_action === 'login') {
$self->response->setStatus(200);
$self->setThemeFile('module/user/login.php');
}
// register / retrieve 同理
}
}{/collapse-item}
路径:usr/themes/joe-master/public/function.php
目标:放开 Typecho 1.3 版本限制;补齐 joe 主题所需路由;修复 1.3 下登录/注册链接生成。
关键改动示例:
1:放开版本限制(允许 >= 1.2)并在 install() 里触发路由自修复:
function install()
{
if (PHP_VERSION < 8) throw new \Typecho\Exception('请使用 PHP 8 及以上版本!');
if (version_compare(\Typecho\Common::VERSION, '1.2', '<')) throw new \Typecho\Exception('请使用 Typecho 1.2 及以上版本!');
ensure_routing_table_for_joe();
// ...
}2:新增 ensure_routing_table_for_joe()(确保 joe/api、goto、user、sitemap 路由存在):
$routes = [
'joe_api' => [
'url' => '/joe/api/[route:alphaslash]',
'widget' => 'Widget_Archive',
'action' => 'render'
],
'joe_goto' => [
'url' => '/goto',
'widget' => 'Widget_Archive',
'action' => 'render'
],
'joe_user' => [
'url' => '/user/[action:alpha]',
'widget' => 'Widget_Archive',
'action' => 'render'
],
'joe_sitemap' => [
'url' => '/sitemap.xml',
'widget' => 'Widget_Archive',
'action' => 'render'
]
];
// ... 如有缺失则写回,并用 Typecho\Router\Parser 重建 routingTable[0]3:user_url() 在 1.3+ 下改为 ?user=xxx 形式:
if (version_compare(\Typecho\Common::VERSION, '1.3.0', '>=')) {
if (str_starts_with($url, '?referer=')) $url = '&referer=' . substr($url, 9);
$url = \Helper::options()->index . '?user=' . $action . $url;
}{/collapse-item}
BASE_API: `<?= joe\root_relative_link(joe\index('joe/api')) ?>/`{/collapse-item}
路径:usr/themes/joe-master/module/head.php
问题:非 single 页面里强制访问 $this->description/$this->keywords,在 Typecho 1.3 + PHP 8 下可能触发 text 字段强类型错误,导致搜索页直接 500。
关键改动:
} else {
// 不再触碰 $this->description / $this->keywords
$this->header('commentReply=&antiSpam=');
}{/collapse-item}
<span class="muted ellipsis"><?php $this->keywords(); ?></span>{/collapse-item}
<?php $permalink = $item['permalink'] ?? \Typecho\Router::url('page', ['slug' => $item['slug']], $this->options->index); ?>
<a href="<?= joe\root_relative_link($permalink) ?>">...</a>{/collapse-item}
<?php $permalink = $item['permalink'] ?? \Typecho\Router::url('page', ['slug' => $item['slug']], $this->options->index); ?>
<a href="<?= joe\root_relative_link($permalink) ?>">...</a>{/collapse-item}
关键改动示例:
joe\root_relative_link($value['permalink'] ?? $value['url'] ?? ''){/collapse-item}
<?php $this->widget('Widget\Metas\Category\Rows')->to($item); ?>{/collapse-item}
补丁文件
完整原版适配文件:
对应修改文件补丁(直接根目录解压覆盖):
注意是在根目录解压,不是主题目录
解决方法作者名单
问题 2&3 解决办法来源于此作者宗同学
问题 4 解决办法来源于此作者Java 小学生
问题 5 解决办法来源作者浅染
总结
在完成上述方法后,你的个人博客在 Typecho1.3.0 基本可恢复正常。
由于 Typecho 1.3.0 在近期发布,以上修复方案均为个人在实际升级过程中的测试整理,可能仍有未覆盖到的特殊场景。
如果你在升级过程中遇到了其他问题,或者有更好的优化建议,欢迎联系进行讨论和补充~