Wordpress WooCommerce 商品分类页顶部分类导航不显示?一次完整的排查与解决记录
一句话总结:一次被 LiteSpeed Cache 坑惨的 WooCommerce 分类。

最近折腾一个 WooCommerce 商店页时,遇到了一个看起来很简单、实际特别折磨人的问题。
商店首页顶部有一组商品分类入口,点击某个分类后会进入对应的商品分类页。正常来说,这组分类导航应该一直保留,方便用户继续切换其他分类。
问题偏偏就出在这里:
Shop 首页显示正常,一进入商品分类页,顶部分类导航就消失了。
更离谱的是,后来改完以后大部分分类恢复正常,唯独其中一个分类死活不显示,而且 PC、移动端一起出问题。
前前后后查了不少东西,最后发现真正把排查方向搅乱的,居然是 LiteSpeed Cache。
把整个过程记下来,免得以后再踩一次。
一开始以为是分类页模板的问题
最开始看到的现象很直观:
在 Shop 页面:
- 顶部 5 个分类正常
- 图片正常
- 点击正常
进入某个 Product Category 页面以后:
- 商品列表正常
- 筛选正常
- 页面标题正常
- 但顶部那组分类没了
第一反应自然是去主题设置里找。
于是把产品归档、Page Title、Product Categories 相关设置翻了一遍。
像什么:
- 显示商品分类
- 显示当前分类祖先
- 隐藏空分类
- 分类层级
- 分类邻居
基本都试了一轮。
结果没什么用。
这时候其实已经开始有点不对劲了:后台设置看起来都是对的,但前台行为和设置完全对不上。
DevTools 反而把问题范围缩小了
后面没有继续盲点设置,而是直接用浏览器 DevTools 看页面到底生成了什么。
先在正常的 Shop 页面检查分类元素。
结果很明确:
category-grid-item = 5
也就是说,5 个分类都真实存在于 DOM 里。
继续往父级结构看,可以看到它们属于类似这样的结构:
category-grid-item
→ carousel item
→ product categories
→ column
→ row
这时就能确认一件事:
顶部这组东西不是简单的菜单,而是 Product Categories 动态区块。
然后再去异常的商品分类页跑同样的检查。
结果变成:
category-grid-item = 0
更关键的是,对应位置的外层 Column 还在:
children = 0
htmlLength = 0
这一下基本把 CSS 排除了。
如果只是:
display: none;
或者:
visibility: hidden;
元素应该还在 DOM 里。
现在是里面压根没有生成内容。
所以问题已经从:
“为什么这个分类导航看不见?”
缩小成了:
“为什么 Product Categories 动态区块在分类归档页没有输出?”
这比盲猜 CSS、响应式、图片加载靠谱得多。
真正的问题在 Product Archive Layout
继续往下查,发现网站实际上使用的是一个 Product Archive Layout。
这个 Layout 同时控制:
- Shop
- Product Category
- 商品归档页
而顶部分类,就是 Layout 里的一个:
Product Categories Block
打开这个区块以后,看到一个很关键的选项:
Data source
原来使用的是:
WooCommerce Query
这里就开始说得通了。
WooCommerce Query 会根据当前归档页面的上下文动态查询。
在 Shop 首页时,没有具体的当前分类,于是它可以正常列出一级分类。
但进入某个具体 Product Category 后,查询上下文发生变化,最终可能拿不到想要的那组一级分类。
于是就出现:
Shop
→ 有分类
Product Category
→ 分类为空
对于“固定显示几个一级分类入口”这种需求,其实根本没必要让它跟着当前分类上下文跑。
于是改成:
Custom Query
并设置:
Count: 5
Order by: Menu order
Hide empty: Off
保存以后,大部分分类立刻恢复正常。
到这里本来以为结束了。
结果新的坑来了。
最诡异的一幕:只有一个分类还是坏的
改成 Custom Query 后:
- Shop 正常
- 分类 A 正常
- 分类 B 正常
- 分类 C 正常
- 分类 D 正常
- 唯独分类 E 还是不显示
这种情况特别容易让人怀疑:
- 这个分类是不是父级不一样?
- 是不是空分类?
- 是不是 Display Type 不一样?
- 是不是有独立 Layout?
- 是不是 taxonomy metadata 有问题?
于是又把正常分类和异常分类逐项对比了一遍。
结果:
Parent = 0
Count = 1
Display type = Default
全部正常。
连分类层级都一样。
DevTools 再看一次:
正常分类页:
categoryItems: 5
catBlockExists: true
异常分类页:
categoryItems: 0
catBlockExists: false
又开始往 Gutenberg Block attributes、隐藏设置这些方向查。
甚至把区块真实保存的 attributes 都翻出来看了。
这里其实已经明显开始“查深了”。
最后才想起来一个最朴素的问题:
缓存清了吗?
最后发现:LiteSpeed Cache 一直在给旧页面续命
网站开着 LiteSpeed Cache。
之前异常分类页已经被访问过,所以 LiteSpeed 把那个“分类区块为空”的旧 HTML 缓存下来了。
之后虽然 Layout 已经改成 Custom Query:
旧配置
WooCommerce Query
↓
新配置
Custom Query
但那个分类 URL 仍然命中服务器缓存。
于是就出现一个极其迷惑的状态:
新访问的分类
→ 第一次生成
→ 使用新 Layout
→ 正常
之前访问过的异常分类
→ 命中旧缓存
→ 继续输出旧 HTML
→ 永远不正常
更坑的是:
Ctrl + F5 没用。
因为 Ctrl + F5 主要解决的是浏览器缓存。
LiteSpeed Cache 是服务器端页面缓存。
浏览器就算刷新一百遍,服务器还是可能把之前缓存好的 HTML 原样扔回来。
最后去:
LiteSpeed Cache
→ Toolbox
→ Purge
→ Purge All LSCache
清掉缓存。
再刷新。
好了。
PC 正常。
移动端正常。
所有分类都正常。
折腾半天,最后卡在缓存。
这次最值得记住的不是“清缓存”
如果只是总结成一句:
WordPress 出问题先清缓存。
那其实没什么价值。
真正有用的是排查顺序。
以后遇到类似:
后台已经改了,但前台行为很奇怪
可以先按下面这个顺序来。
1. 先看 DOM 到底有没有生成
不要第一时间改 CSS。
先确认:
元素存在,只是不可见
还是:
元素压根没有生成
这是两个完全不同的问题。
前者查:
- CSS
- JS
- responsive state
后者查:
- PHP
- query
- dynamic block
- archive context
- template condition
2. 动态区块一定要考虑“当前页面上下文”
尤其是 WooCommerce 归档页。
Shop 和 Product Category 看起来很像,但查询上下文根本不是一回事。
类似:
WooCommerce Query
Current Query
Current Taxonomy
Current Category
这种选项都意味着:
同一个 Block 在不同 URL 下可能得到完全不同的结果。
如果需求只是:
永远显示固定的几个一级分类
那 Custom Query 往往比自动跟随当前页面上下文更可控。
3. 一个页面异常、其他同类页面正常时,优先怀疑缓存
这是这次最容易忽略的信号。
假设有 5 个结构完全相同的分类:
4 个正常
1 个异常
并且:
- Layout 一样
- 分类配置一样
- 数据一样
- 页面结构理论上一样
这时候不要立刻往“这个分类是不是有什么神秘配置”上钻。
先问一句:
这个 URL 有没有可能缓存过旧版本?
尤其用了:
- LiteSpeed Cache
- Cloudflare
- WP Rocket
- Nginx FastCGI Cache
- CDN Page Cache
这种东西时。
4. Ctrl + F5 不等于清服务器缓存
这次最大的认知坑就是这个。
简单说:
Ctrl + F5
≈ 浏览器别用本地旧资源
而:
Purge LiteSpeed Cache
≈ 服务器别再给我旧页面
根本不是一个层级。
以后改:
- WooCommerce 分类
- Archive Layout
- Gutenberg 动态区块
- 商品筛选
- 模板条件
- 页面 Builder
最好养成一个习惯:
保存
→ Purge LSCache
→ Ctrl + F5
→ 再测试
开发阶段甚至可以考虑暂时减少页面缓存干扰,等结构稳定以后再正式开启。
最后的方案
最终没有:
- 改主题源码
- 写 PHP
- 注入 JS
- 写 CSS Hack
- 重做分类导航
- 加额外插件
只用了原本就有的:
Product Archive Layout
→ Product Categories
→ Custom Query
然后把 LiteSpeed 的旧缓存清掉。
这也是我比较满意的结果。
遇到 WordPress 这类成熟系统时,能用主题和插件本身提供的能力解决,尽量别急着往源码上打补丁。
因为很多时候并不是功能做不到。
只是:
你改的是现在,缓存给你看的还是过去。
更多推荐



所有评论(0)