没有不值得去解决的问题,也没有不值得去学习的技术!

WordPress 分类下拉列表跳转优化:告别 ?category_name=,直接进入最终分类链接

图 4:修改生效后,从分类下拉列表直接进入 Bootstrap 5 最终分类固定链接,不再出现 category_name 中转地址。

作者:

从经典到块:主题迁移

从Hueman到Twenty Twenty-Five,主题切换与多语言菜单配置

(1) 从Hueman到Twenty Twenty-Five,主题切换与多语言菜单配置

经过以上步骤,语言切换器最终在页面上的效果符合预期。(见图 9)

(2) 在 WordPress 2025 主题中,把 Polylang 语言切换器移到右上角的完整记录

页眉导航宽度异常问题:导航被内容宽度限制(图 4)

(3) WordPress Twenty Twenty-Five 全局宽度布局实操笔记:宽屏全幅+大屏限宽配置方案

中文(中国)前台首页:66主内容文章+33标准化侧边栏,区块正常显示(对应图6)

(4) 实操|WordPress Twenty Twenty-Five 区块主题 Text Blog Home 改造经典两栏首页(双语无损适配)

改造完成最终首页效果(图5)

(5) WordPress Twenty Twenty-Five 两栏首页改造:Text Blog 小图列表模板完整实操记录

图11:样式重写后下拉美观,但层级子分类在原生 Option 标签下以空格缩进表示

(6) 分类列表下拉菜单的美化与渲染机制调试实录

图3:应用修正后的 CSS,日历占据了应有的侧边栏宽度,有文章的日子用主题同色系进行了高亮,悬停时会变黑

(7) 修复日历在侧边栏“占不满”的问题:WordPress 2025 主题日历样式优化

图5:English 下的页面显示第二个 Language Visibility 区块

(8) 为博客首页侧边栏添加多语言「个人品牌」区块

图4:调整后的分页效果

(9) 一次 FSE 分页丢失的排查与修复:从纯布局样板到查询循环

在英文页面(https://www.shuijingwanwq.com/en/)中,日历上每个日期点击后跳转的链接仍然是 https://www.shuijingwanwq.com/2026/06/08/ 的形式,而不是预期的 https://www.shuijingwanwq.com/en/2026/06/08/。

(10) WordPress 2025 主题 + Polylang:修复日历链接缺少语言目录的完整记录

图4:中文站点,下拉菜单样式美观,显示“选择年份”。

(11) 优化 WordPress 2025 主题页脚:多语言导航、社交链接与归档下拉栏的完整改造记录

图2:分类页单栏效果

(12) 从单栏到两栏:WordPress分类页统一首页侧边栏及列表结构的实操记录

套用上述代码后,标签云立刻有了质的飞跃:

(13) 告别参差不齐!只用 CSS 打造适配 2025 主题的现代标签云

搜索“alipay”的结果,每篇文章都带了一张大尺寸的特色图片,紧跟着就是完整的正文内容。我的文章里还有代码片段,全都被拉出来显示在列表里,页面无限拉长,排版也乱糟糟的。如图1

(14) 搜索结果页太长了?我给WordPress 2025主题做了一次“断舍离”

在英文页面 https://www.shuijingwanwq.com/en/ 中,22 号显示蓝色链接

(15) WordPress 日历在 Polylang 多语言环境下的兼容性修复实践

Network检查确认:如图3

(16) WordPress主题迁移:Emoji处理代码是否需要保留?

图2 Site Wide Header

(17) WordPress 标签页 noindex 优化:从主题迁移到代码重构的实践分享

最近,我在检查我的 WordPress 网站时,发现浏览器开发者工具的控制台里出现了几个令人不安的红色错误信息:

(18) WordPress 控制台报错排查实录:从 jQuery 冲突到百度统计警告

再次无效后,我决定使用Auto Insert,Location选择"Frontend Only",并在代码中确定插入位置(图5)。

(19) 从Ad Inserter到WPCode:CTA配置迁移与优先级实现

我重新审视了这篇文章的内容,发现文章中直接包含了 WPCode 的简码调用:wpcode。如图4

(20) 记一次由 WPCode 简码引发的 WordPress 500 致命错误排查全记录

图6:Chrome无痕模式下,Logo和Favicon均显示正常

(21) 记一次 WordPress 2025 主题 Logo 与 Favicon 的折腾之旅

新的实现方式:基于WPCode Location的优化方案

(22) 从Ad Inserter到WPCode:CTA配置迁移与优化实践

初始配置(图1)

(23) WPCode代码片段插入顺序问题:理论与实践的差距

图 2:区块右侧面板的“额外 CSS”输入框。

(24) 优化 WordPress 热门文章列表间距,提升阅读体验

页面底部出现横向滚动条。

(25) WordPress 页面出现横向滚动条?一次从 CSS 到区块编辑器的完整排查记录

图 3:最终效果——浏览器标签栏、WordPress 编辑器及网站 Logo 显示正常,方块感基本消失

(26) AI 生成的 Logo 还有白边?借助 ChatGPT Plus,彻底解决 WordPress Favicon 方块感

图 4:控制台出现 availableWidth=0

(27) WordPress 归档页 AdSense 报错 availableWidth=0:从横向滚动条到 Gutenberg 区块结构的排查全过程

从经典到块(终章):主题迁移结束,我决定停止折腾

(28) 从经典到块(终章):主题迁移结束,我决定停止折腾

图3:WebPageTest 总览

(29) 🧪 WordPress 主题性能对比实测:Hueman vs Twenty Twenty-Five(CDN上线前基线)

图1:移动端访问旧文章时,图片没有正常居中缩放

(30) WordPress 旧文章移动端图片错位排查:经典编辑器 Caption 固定宽度与缓存验证全过程

如图4:最终 Header 展示效果

(31) Header 诗词微内容系统实战:从动态动画到稳定静态组件的收敛过程

图 4:中文首页完整摘要效果

(32) WordPress 双语文章列表摘要完整显示实战:WPCode + Gutenberg Post Excerpt 的最终验证

图 4:修改生效后,从分类下拉列表直接进入 Bootstrap 5 最终分类固定链接,不再出现 category_name 中转地址。

(33) WordPress 分类下拉列表跳转优化:告别 ?category_name=,直接进入最终分类链接

最近重新检查 WordPress 首页时,我发现分类下拉列表又出现了一个似曾相识的问题。

在首页右侧的分类下拉列表中选择 PHP Simple HTML DOM Parser 后,浏览器访问的是:

Plaintext
https://www.shuijingwanwq.com/?category_name=php-simple-html-dom-parser

但页面并没有继续进入真正的分类归档,而是仍然显示了首页内容。

图 1:分类下拉列表仍然通过 category_name 查询参数跳转,而当前页面没有进入对应分类归档。
图 1:分类下拉列表仍然通过 category_name 查询参数跳转,而当前页面没有进入对应分类归档。

这个现象让我很快想到了之前做过的两次调整:一次是分类下拉列表的多语言域名修复,另一次则是针对 CDN Query String 的缓存优化。

这两个原本各自正常的功能,在后来组合到一起后,产生了新的冲突。

一、这个分类下拉列表,其实以前已经修过一次

2026 年 7 月 13 日,在将 WordPress 英文站迁移到独立子域名之后,我曾经处理过一次分类下拉列表跳转错误。

当时的完整排查过程记录在 《WordPress Polylang 英文子域名迁移后链接仍指向中文站:分类下拉、面包屑与区块模板的完整修复》 中。(水晶湾物业)

发布到 WordPress 时,这类正文链接均设置为“在新标签页中打开”。

当时最明显的问题,是英文首页选择 Browser 分类以后,分类 slug 明明属于英文分类,但跳转 URL 使用的却仍然是中文主域名。文章中最终确认,英文分类数据和正式分类固定链接本身都没有问题,错误主要发生在分类下拉列表生成的跳转地址上。(水晶湾物业)

当时修复完成后的流程仍然是:

Plaintext
选择分类

生成 /?category_name=分类别名

WordPress 解析 category_name

跳转到最终分类固定链接

例如:

Plaintext
https://en.shuijingwanwq.com/?category_name=browser-en

随后再进入:

Plaintext
https://en.shuijingwanwq.com/category/application-tool-en/browser-en/

这套方式当时是可以正常工作的。

二、后来做的 Query String 优化,让这个问题重新暴露出来

到了 2026 年 8 月 3 日,我又针对 WordPress 页面缓存和 CDN Cache Key 做了一次 Query String 归一化优化。

相关过程记录在 《从 EdgeOne 524 到 Query String 归一化:WordPress 文章与公开列表页 CDN 缓存优化实战》 中。

这次优化的核心目标,是避免一些不会改变页面内容的查询参数不断生成新的缓存版本。

例如对于普通公开页面而言:

Plaintext
/

与:

Plaintext
/?random=123

如果最终页面内容完全相同,就没有必要分别维护一份页面缓存。

这个优化方向本身没有问题。

但重新测试分类下拉列表以后,我意识到:

Plaintext
category_name

并不是普通的无意义 Query String。

它承担了 WordPress 分类下拉列表的实际跳转功能。

于是就出现了这样一条冲突链路:

Plaintext
分类下拉列表

生成 ?category_name=slug

CDN Query String 归一化

category_name 没有继续按照原来的方式影响请求

WordPress 得到的效果接近普通首页

最初很容易想到的修复方式,是继续修改 EdgeOne 或 Cloudflare 规则,把:

Plaintext
category_name

也加入需要保护的功能性 Query String。

但再往前想一步,我发现还有一个更简单的问题:

为什么分类下拉列表一定要先经过 ?category_name=

三、既然已经知道最终地址,为什么不直接跳过去?

WordPress 分类真正需要访问的其实是标准分类固定链接。

例如 PHP Simple HTML DOM Parser 的最终地址是类似:

Plaintext
/category/web-devel/html-parser/php-simple-html-dom-parser/

那么现在的链路:

Plaintext
选择分类

/?category_name=slug

WordPress 再解析

最终分类地址

完全可以简化成:

Plaintext
选择分类

最终分类地址

这样带来的好处很直接。

第一,少了一层中间请求。

第二,分类下拉列表不再依赖 Query String。

第三,它与 CDN 的 Query String 缓存规则彻底解耦。

第四,分类归档本来就是标准固定链接形式,后续缓存策略也更加直观。

不过这里不能简单地按照 slug 自己拼:

Plaintext
/category/php-simple-html-dom-parser/

因为我的 WordPress 分类存在父子层级。

真正地址可能是:

Plaintext
/category/web-devel/html-parser/php-simple-html-dom-parser/

所以最终 URL 仍然应该由 WordPress 自己生成,而不是在 JavaScript 中猜测路径。

四、继续使用 WPCode,不修改 Twenty Twenty-Five

这次我仍然选择使用 WPCode 完成调整,而不是直接修改 Twenty Twenty-Five 主题文件。

原来的代码片段名称是:

Plaintext
修复非默认语言站分类下拉列表跳转域名

它的职责主要是解决 7 月 13 日发现的英文站跳回中文主域名问题。

现在功能已经发生变化,因此我将它改名为:

Plaintext
分类下拉列表直接跳转最终分类链接

没有重新创建第二份代码片段,而是直接修改原来的代码。

这样可以避免两份 JavaScript 同时监听同一个分类下拉列表。

图 2:继续沿用原来的 WPCode 代码片段,将功能升级为直接访问最终分类固定链接。
图 2:继续沿用原来的 WPCode 代码片段,将功能升级为直接访问最终分类固定链接。

五、页面范围尽量交给 WPCode,而不是继续堆 PHP 判断

这次调整时,我也继续采用最近比较喜欢的 WPCode 使用方式:

能通过 Location 与 Smart Conditional Logic 完成的页面判断,就不要再重复写进 PHP。

代码片段使用:

Plaintext
Code Type:
PHP Snippet

Insert Method:
Auto Insert

Location:
Frontend Conditional Logic

最开始我考虑只限制在 Homepage。

但实际检查后发现,分类下拉列表不仅存在于首页,在分类等归档页面中同样存在。

因此最终配置为:

Plaintext
Type of Page → Is → Homepage

OR

Type of Page → Is → Archive
图 3:代码片段仅在首页或归档页执行,页面范围交给 WPCode 配置层管理。
图 3:代码片段仅在首页或归档页执行,页面范围交给 WPCode 配置层管理。

这样一来,PHP 代码中就没有必要重复维护类似:

PHP
is_front_page()
is_home()
is_archive()
is_admin()

这样的页面条件。

WPCode 负责回答:

哪些页面需要执行?

PHP 代码只负责回答:

分类下拉列表应该怎样直接跳到最终 URL?

职责会清晰很多。

六、最终代码

最终使用的 WPCode 代码如下:

PHP
/**
 * SWQ:分类下拉列表直接跳转最终分类链接。
 */
add_filter(
    'render_block_core/categories',
    function ( $block_content, $block ) {

        if ( empty( $block['attrs']['displayAsDropdown'] ) ) {
            return $block_content;
        }

        $processor = new WP_HTML_Tag_Processor( $block_content );

        while ( $processor->next_tag( 'option' ) ) {
            $slug = $processor->get_attribute( 'value' );

            if ( empty( $slug ) || '-1' === $slug ) {
                continue;
            }

            $term = get_term_by( 'slug', $slug, 'category' );

            if ( ! $term || is_wp_error( $term ) ) {
                continue;
            }

            $url = get_term_link( $term );

            if ( is_wp_error( $url ) ) {
                continue;
            }

            $processor->set_attribute(
                'data-swq-term-url',
                $url
            );
        }

        $block_content = $processor->get_updated_html();

        static $script_added = false;

        if ( ! $script_added ) {
            $script_added = true;

            $block_content .= <<<'HTML'
<script>
document.addEventListener('change', function (event) {
    const dropdown = event.target;

    if (!(dropdown instanceof HTMLSelectElement)) {
        return;
    }

    const option = dropdown.options[dropdown.selectedIndex];
    const url = option?.dataset.swqTermUrl;

    if (!url) {
        return;
    }

    event.stopPropagation();
    window.location.assign(url);
}, true);
</script>
HTML;
        }

        return $block_content;
    },
    20,
    2
);

这里并没有粗暴地把 <option> 原来的 value 从 slug 修改成 URL。

原来的结构仍然保留,例如:

HTML
<option value="php-simple-html-dom-parser">

只是在渲染时额外增加最终分类 URL,大致类似:

HTML
<option
    value="php-simple-html-dom-parser"
    data-swq-term-url="https://www.shuijingwanwq.com/category/web-devel/html-parser/php-simple-html-dom-parser/"
>

当用户重新选择分类时,JavaScript 读取:

Plaintext
data-swq-term-url

然后:

JavaScript
window.location.assign(url);

直接进入最终地址。

最重要的是,最终 URL 来自:

PHP
get_term_link()

而不是自己拼接。

这样父子分类结构、分类 slug,以及中文站和英文站各自的域名,都继续交给 WordPress 和现有多语言体系处理。

七、这次没有急着清缓存

修改 WPCode 后,我没有马上清理所有页面缓存和 CDN 缓存。

因为旧页面已经存在缓存,如果马上手工清除所有缓存,很难观察自然缓存生命周期之后实际访客得到的结果。

因此这一次直接等待缓存自然过期。

从 8 月 8 日完成修改,到 8 月 14 日再次检查,中间没有因为测试结果焦虑而继续修改代码。

几天后再测试,看到的已经是自然更新后的页面。

八、8 月 14 日进行四组实际验证

缓存自然过期以后,我重新测试了四种场景:

  1. 中文首页 → 选择一个分类
  2. 中文归档页 → 选择一个分类
  3. 英文首页 → 选择一个分类
  4. 英文归档页 → 选择一个分类

四项全部通过。

现在正常操作分类下拉列表时,浏览器已经不需要再经过:

Plaintext
/?category_name=xxx

而是直接进入最终分类固定链接。

例如在中文归档页面选择 Bootstrap 5 后,浏览器直接进入:

Plaintext
https://www.shuijingwanwq.com/category/web/html-css/css-framework/bootstrap/bootstrap-5/
图 4:修改生效后,从分类下拉列表直接进入 Bootstrap 5 最终分类固定链接,不再出现 category_name 中转地址。
图 4:修改生效后,从分类下拉列表直接进入 Bootstrap 5 最终分类固定链接,不再出现 category_name 中转地址。

这正是这次修改最核心的验证结果。

九、最终没有为了它修改 EdgeOne 和 Cloudflare

发现问题之初,还有一种完全可以实施的方案:

Plaintext
保留 ?category_name=
+
在 CDN 中把 category_name 加入功能性 Query String 例外

但最终我没有这样做。

原因也很简单。

新的分类下拉逻辑生效以后,正常用户已经不会再通过:

Plaintext
/?category_name=xxx

访问分类。

既然业务链路已经不需要这个中间查询参数,自然没有必要再让 EdgeOne 和 Cloudflare 专门为它增加一套例外。

最终两层职责变成:

Plaintext
CDN

继续负责现有 Query String 归一化与页面缓存

WordPress 分类下拉列表

直接访问标准分类固定链接

两者不再互相依赖。

这比继续不断扩大 Query String 白名单要简单得多。

十、这次真正解决的,不只是一个跳转错误

一开始看到:

Plaintext
/?category_name=php-simple-html-dom-parser

失效时,我最先想到的仍然是:

再给 CDN 加一个例外。

这是面对兼容问题时非常自然的思路。

但这次最后的解决方式让我觉得更值得记录:

与其不断给后来增加的规则补例外,不如先看看旧业务链路里有没有本来就可以删除的中间层。

原来的结构:

Plaintext
分类下拉列表

category_name

WordPress 查询参数解析

最终分类固定链接

现在变成:

Plaintext
分类下拉列表

最终分类固定链接

少了 Query String,少了一次中转,也少了一层和 CDN 的耦合。

同时,这次也进一步确定了我现在使用 WPCode 时比较倾向的一种方式:

Plaintext
Location / Enable Logic

负责“在哪里运行”

PHP / JavaScript

只负责“运行什么”

能交给配置界面的页面判断,就尽量不再塞进代码。

这样不仅代码更精简,以后几个月甚至几年后重新查看这个代码片段时,也更容易快速理解它的职责。

总结

这次 WordPress 分类下拉列表问题,最开始看起来只是 Query String 缓存策略带来的一个兼容性回归。

但最终并没有通过增加:

Plaintext
category_name

缓存例外来修复。

而是把整个分类跳转链路进一步简化为:

Plaintext
WPCode
+
render_block_core/categories
+
WP_HTML_Tag_Processor
+
get_term_link()
+
JavaScript 直接跳转最终 URL

代码片段则通过 WPCode 限定在:

Plaintext
Homepage OR Archive

等待缓存自然过期后,中文首页、中文归档页、英文首页、英文归档页四种场景全部验证通过。

至此,正常的分类下拉列表访问已经不再依赖:

Plaintext
?category_name=

而是一步进入最终 /category/.../ 固定链接。

这次优化看起来只是少掉一个 Query String,但真正减少的是业务跳转逻辑与 CDN 缓存规则之间不必要的耦合

Header 诗词微内容系统实战:从动态动画到稳定静态组件的收敛过程

WordPress 网站维护、性能优化与博客运营咨询

本站已持续运营超过 10 年,累计发布 1000+ 篇原创技术文章,长期实践 WordPress 网站建设、CDN / Cloudflare 配置、缓存优化、Google SEO、广告变现和多语言网站运营。

如果你的 WordPress 网站遇到访问慢、缓存异常、插件冲突、广告不显示、SEO 基础结构混乱、CDN 配置不确定等问题,可以联系我做一次远程技术排查。

适合以下用户:
✅ 个人博客站长
✅ WordPress 网站运营者
✅ 独立开发者与内容创作者
✅ SaaS 产品官网运营团队
✅ 希望优化网站速度与稳定性的站点

服务内容:
✅ WordPress 速度优化
✅ Cloudflare / CDN / 缓存配置排查
✅ 插件冲突与页面异常排查
✅ AdSense 广告显示问题排查
✅ SEO 基础结构检查
✅ 博客运营与商业化咨询

如需了解方案或交流相关问题,请直接联系我,并注明:WordPress 维护咨询

联系方式:
Telegram:@shuijingwan
微信:13980074657
邮箱:shuijingwanwq@gmail.com

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理