Typecho Joe主题导航菜单bug修复
标签搜索

Typecho Joe主题导航菜单bug修复

hcl
hcl
2026-04-08 / 0 评论 / 16 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2026年08月07日,已超过56天没有更新,若内容或图片失效,请留言反馈。

1. Bug 现象描述

在将 Typecho 博客程序升级到最新版本 1.3.x 后,使用 Joe 主题时,顶部和侧边栏的独立页面导航菜单(例如“瞬间”、“留言板”、“关于”等)链接集体失效。具体表现为:所有独立页面的链接全部变成了网站的首页地址,点击后仅会刷新跳转回首页,无法正常访问相应的独立页面。

2. 问题原因分析

该 Bug 的核心原因在于 Joe 主题获取页面列表数据的语法在 Typecho 1.3 版本中由于核心更新而失效。

为了实现后台设置的“导航菜单最大显示数量(JNavMaxNum)”以及超出后的“更多”下拉菜单功能,Joe 主题的原作者在代码中没有采用 Typecho 官方标准的迭代方法,而是直接提取了组件底层的原始数据源集合(即 $pages->stack)进行 foreach 循环。

代码差异导致的问题:
在 Typecho 1.2.1 及更早版本中,$pages->stack 数组在初始化时直接持有了 permalink(固定链接)等属性,所以直接获取 $item['permalink'] 碰巧是有效的。
然而,在 Typecho 1.3 的代码更新中,permalink、slug 等依赖路由解析的衍生属性调整为了动态加载。如果未调用官方数据解析接口 $pages->next() ,而是强行绕过 API 直接读取底层数组 $item['permalink'],将无法获取正确解析后的链接,导致返回值为空。最终,前端的 HTML href 属性输出异常,被浏览器默认解析为了网站根目录(首页)。

3. 完美修复方案

要解决这个问题,我们需要兼顾 Joe 主题的“数量限制与折叠”功能,同时严格遵循 Typecho 的官方规范。只需通过 $pages->next() 接口先行安全遍历数据,将其转存到一个新数组中,再对新数组进行逻辑切片和输出即可。这不仅能完美修复 1.3 下的 Bug,同时代码也能向下兼容老版本。

修复步骤详解

请在你的 Joe 主题源码目录中,找到并打开 public/header.php 文件。

第一步:修复顶部 PC 端导航

在 header.php 文件中找到第 84 行附近(顶部导航输出区域):

修改前:

        <?php $this->widget('Widget_Contents_Page_List')->to($pages); ?>
        <?php if (count($pages->stack) <= $this->options->JNavMaxNum) : ?>
          <?php foreach ($pages->stack as $item) : ?>

修改后:

        <?php
        $this->widget('Widget_Contents_Page_List')->to($pages);
      
        // 【新增】安全解析:使用标准 API 取出并构建完整页面属性数组
        $pageItems = [];
        while ($pages->next()) {
            $pageItems[] = [
                'slug' => $pages->slug,
                'permalink' => $pages->permalink,
                'title' => $pages->title
            ];
        }
        ?>
        <?php if (count($pageItems) <= $this->options->JNavMaxNum) : ?>
          <?php foreach ($pageItems as $item) : ?>

注意: 替换完毕后,请紧接着将该判断逻辑下方所有的 $pages->stack 都替换为我们刚刚构建好的 $pageItems。例如,原来代码中的 array_slice($pages->stack, ...) 需要统一修改为 array_slice($pageItems, ...)。

第二步:修复侧边栏 / 移动端导航

在同一个 header.php 文件中继续向下寻找,定位到第 378 行附近(侧边栏页面列表输出区域):

修改前:

        <ul class="slides panel-body">
          <?php foreach ($pages->stack as $item) : ?>
            <li>
              <a class="link <?php echo $this->is('page', $item['slug']) ? 'current' : '' ?>" href="<?php echo $item['permalink'] ?>" title="<?php echo $item['title'] ?>"><?php echo $item['title'] ?></a>
            </li>
          <?php endforeach; ?>
        </ul>

修改后(直接将 $pages->stack 替换为 $pageItems 即可):

        <ul class="slides panel-body">
          <?php foreach ($pageItems as $item) : ?>
            <li>
              <a class="link <?php echo $this->is('page', $item['slug']) ? 'current' : '' ?>" href="<?php echo $item['permalink'] ?>" title="<?php echo $item['title'] ?>"><?php echo $item['title'] ?></a>
            </li>
          <?php endforeach; ?>
        </ul>

4. 完成

保存对 header.php 的修改,刷新你的博客。测试点击顶部的“留言板”等独立页面,你就会发现熟悉且正常的导航功能又回来啦!

1

评论 (0)

取消