使用pre_get_posts修改主查询后,Elementor WooCommerce产品组件仍显示全目录?
问题
我希望基于商品ID,在Elementor产品图库中展示指定的WooCommerce商品。但当前版本的Elementor的Products和Product Archives小部件不支持Query ID,因此尝试了Elementor自定义查询过滤器文档之外的替代方法,代码如下:
// Hook into 'init' to check for the '/shop' endpoint add_action('init', function() { if ($_SERVER['REQUEST_URI'] == '/shop') { if (!session_id()) { session_start(); } // Add action to modify the main query on the 'shop' page, firing on the pre_get_posts hook add_action('pre_get_posts', 'modify_shop_page_query', 1); } }); // Modify the main query on the '/shop' URI to display specific products function modify_shop_page_query($query) { if (!is_admin() && $query->is_main_query()) { if (isset($_SESSION['searched_product_ids']) && !empty($_SESSION['searched_product_ids'])) { $product_ids = $_SESSION['searched_product_ids']; // When logging is enabled, this line proves on each request that the product ID array is correctly making it this far: error_log(json_encode($product_ids)); // Example output: "[155348,162360,162444,180967,179510,163383,165519,167079]" $query->set('post_type', 'product'); $query->set('post__in', $product_ids); $query->set('orderby', 'post__in'); } } }
代码中已验证商品ID数组能正确传递,但将Elementor产品组件的查询设置为Current Query后,图库仍显示全部商品目录,推测$query被绕过或忽略。请问此方案是否可行?
分析与解决
这个方案不可行,核心原因是:Elementor的Products小部件即便设置为「Current Query」,也不会直接复用WordPress的主查询(main query)。Elementor会在内部独立构建查询对象,你通过pre_get_posts修改的主查询,对小部件的自定义查询完全不起作用。
正确的解决方式是直接针对Elementor的查询钩子进行修改,替代代码如下:
// 初始化session(全局执行,无需限定shop页面) add_action('init', function() { if (!session_id()) { session_start(); } }); // 过滤Elementor Products小部件的查询参数 add_filter('elementor/query/query_args', function($query_args, $widget) { // 仅对Products小部件生效,且当前是shop页面 if ($widget->get_name() === 'products' && is_shop()) { if (isset($_SESSION['searched_product_ids']) && !empty($_SESSION['searched_product_ids'])) { $product_ids = $_SESSION['searched_product_ids']; // 确保ID是整数类型,避免查询异常 $product_ids = array_map('intval', $product_ids); $query_args['post_type'] = 'product'; $query_args['post__in'] = $product_ids; $query_args['orderby'] = 'post__in'; } } return $query_args; }, 10, 2);
使用时注意:
- 将Elementor Products小部件的查询设置改为「Custom Query」,而非「Current Query」,这样钩子才能正确拦截并修改查询参数。
- 移除之前的
pre_get_posts相关代码,避免不必要的冲突。 - 确保session中的商品ID是整数数组,否则会导致查询匹配失败。
内容的提问来源于stack exchange,提问作者BieberFantasy
相关产品推荐
相关产品推荐

