如何根据页面/产品类别程序化切换菜单?排查get_queried_object()返回null问题
get_queried_object()返回null的菜单切换问题 咱们先捋清楚核心问题:这个函数在产品类别页面返回null,大概率是代码执行时机太早,或者页面的主查询被自定义代码/插件干扰了。下面给你一步步排查和解决的方案:
1. 把代码放到WP查询完成后的钩子执行
get_queried_object()依赖WordPress的主查询结果,如果你的代码在wp钩子之前运行(比如直接扔在主题functions.php顶部,或者用了过早的钩子),那时候主查询还没跑完,自然拿不到对象。
把菜单切换逻辑放到template_redirect或者wp钩子里,示例代码如下:
add_action('template_redirect', 'switch_menu_for_product_categories'); function switch_menu_for_product_categories() { // 直接用WooCommerce的条件标签判断,不用依赖get_queried_object() if (is_product_category(['cat1', 'cat2', 'cat3'])) { // 切换到对应分类菜单 add_filter('wp_nav_menu_args', function($args) { if ($args['theme_location'] == 'primary') { // 替换成你的菜单位置标识 $args['menu'] = 'category-specific-menu'; // 替换成目标菜单的ID/名称 } return $args; }); } else { // 默认使用MAIN菜单 add_filter('wp_nav_menu_args', function($args) { if ($args['theme_location'] == 'primary') { $args['menu'] = 'MAIN'; } return $args; }); } }
2. 绕开get_queried_object(),直接用条件标签判断
其实WooCommerce的is_product_category()本身就可以直接判断当前是否是指定产品类别页面,完全不用先获取queried object。比如你可以直接写:
if (is_product_category('cat1') || is_product_category('cat2')) { // 切换菜单逻辑 }
这种方式更可靠,也避免了依赖get_queried_object()的问题。
3. 排查是否有代码干扰主查询
如果上面的方法还是不行,那可能是主题或插件里的代码修改了产品类别页面的主查询。比如用pre_get_posts钩子时,没正确判断查询类型,导致产品类别的主查询被篡改。
你可以先暂时禁用所有插件,切换到WooCommerce官方默认主题(比如Storefront),看看问题是否消失。如果消失了,再逐个恢复插件/主题,找出干扰的那个。
4. 检查缓存插件的影响
如果你的网站用了缓存插件(比如WP Rocket、W3 Total Cache),可能缓存了错误的页面状态,导致get_queried_object()返回null。可以尝试清除全站缓存,或者在缓存设置里排除产品类别页面的缓存,确保缓存插件能正确识别WooCommerce的动态内容。
内容的提问来源于stack exchange,提问作者JoshTalk

