Typecho 1.3.0+ 与 Joe 7.7.1 主题不兼容导致首页文章一直loading的解决方案

Typecho 1.3.0+ 与 Joe 7.7.1 主题不兼容导致首页文章一直loading的解决方案

Simuoss
2025-09-21 / 3 评论 / 18 阅读 / 正在检测是否收录...

前言

昨天迁移完博客站就睡了,今早发现博客站换上Joe主题后,首页文章列表竟然无法正常加载,一直显示loading如图:

后台和控制台也没有任何报错
文章列表无法加载,通常是数据库查询或Widget调用问题。怀疑是Typecho 1.3.0改了一些关键实现,于是开始Debug,发现如下:

Typecho 1.3.0 的变化

  1. 负责处理数据查询、模板渲染等功能的Widget系统经过重构
  2. 数据库访问层从简单的静态调用升级为更现代的面向对象设计

    命名空间变化

    Typecho在1.3.0版本中引入了现代PHP的命名空间机制:

  3. 旧版本: Typecho_Db::get()
  4. 新版本: Typecho\Db::get()

    Widget类体系重构

  5. 旧版本: Widget_Abstract_Contents
  6. 新版本: Widget\Base\Contents 或 Widget\Contents\Post\Admin

    路由系统升级

  7. 旧版本使用 Typecho_Router::post()
  8. 新版本的路由注册机制发生了变化

解决思路

概览

了解了问题在哪,就可以着手解决了。处理这个变动,只需要把类似$db = Typecho_Db::get();的语句改为$db = Typecho\Db::get();即可。
为了保证前向兼容,可以这样写:

/* 兼容Typecho 1.3.0+的数据库类 */
if (class_exists('Typecho\Db')) {
    $db = Typecho\Db::get();
} else {
    $db = Typecho_Db::get();

修改步骤

第一步:修复Widget类继承问题

文件:widget.php
问题: Joe主题的自定义Widget类继承了旧版本的类名

// 原代码
class Widget_Contents_Hot extends Widget_Abstract_Contents

修复: 添加版本检测和兼容性处理

/* 兼容Typecho 1.3.0+版本检测 */
if (class_exists('Widget\Base\Contents')) {
    // 新版本基类
    class Widget_Contents_Hot extends Widget\Base\Contents {
        // ... 实现代码
    }
} else {
    // 旧版本基类  
    class Widget_Contents_Hot extends Widget_Abstract_Contents {
        // ... 实现代码
    }
}

同时修复了数据库排序常量:

// 旧版本
->order('table.contents.created', Typecho_Db::SORT_DESC)
// 新版本兼容
->order('table.contents.created', 'DESC')

第二步:修复路由系统

文件: core.php
问题: 旧版本的路由注册方式在新版本中失效
修复: 添加路由系统兼容代码

/* 兼容Typecho 1.3.0+的路由系统 */
if (class_exists('Typecho\Router')) {
    // 新版本路由注册
    if (method_exists('Typecho\Router', 'post')) {
        Typecho\Router::post('/joe/api', 'Joe_Action');
    }
} else {
    // 旧版本路由注册
    Typecho_Router::post('/joe/api', 'Joe_Action');
}

第三步:修复数据库调用
修复的文件:

  • functions.php
  • function.php
  • route.php
    问题: 所有直接调用 Typecho_Db::get() 的地方都会在新版本中报错
    修复策略: 在每个数据库调用前添加版本检测

    /* 兼容Typecho 1.3.0+的数据库类 */
    if (class_exists('Typecho\Db')) {
      $db = Typecho\Db::get();
    } else {
      $db = Typecho_Db::get();
    }

    第四步:添加类别名映射
    文件: factory.php
    解决思路: 为了让旧代码能够无缝使用新类名,添加类别名映射:

    /* 兼容Typecho 1.3.0+的Widget Helper Form类 */
    if (class_exists('Typecho\Widget\Helper\Form')) {
      class_alias('Typecho\Widget\Helper\Form', 'Typecho_Widget_Helper_Form');
    }
    
    /* 兼容Typecho 1.3.0+的数据库类 */
    if (class_exists('Typecho\Db')) {
      class_alias('Typecho\Db', 'Typecho_Db');
    }
    
    /* 兼容Typecho 1.3.0+的Widget类 */
    if (class_exists('Typecho\Widget')) {
      class_alias('Typecho\Widget', 'Typecho_Widget');
    }
    
    /* 兼容Typecho 1.3.0+的Abstract Contents类 */
    if (class_exists('Widget\Contents\Post\Admin')) {
      class_alias('Widget\Contents\Post\Admin', 'Widget_Abstract_Contents');
    } elseif (class_exists('Widget\Base\Contents')) {
      class_alias('Widget\Base\Contents', 'Widget_Abstract_Contents');
    }

最终能用的版本

如果你感觉手动修改有些麻烦,也可以直接使用我改好的版本:
Joe7.7.1-typecho1.3.0-fix.zip

0

评论 (3)

取消
  1. 头像
    笔记堡
    Android · Google Chrome

    博主,joe主题在typecho1.3.0版本上,页面链接无法正确生成链接,你可以看看怎么解决。

    回复
  2. 头像
    笔记堡
    Android · Google Chrome

    点击页面分类下面的友联,跳转当前阅览的页面,并不是相应的友联页面,只要是页面下的链接都是这样。

    回复
  3. 头像
    大帅逼
    Windows 10 · Google Chrome

    画图

    回复