子主题functions.php中WooCommerce钩子失效,产品过滤器异常求助
解决WooCommerce产品过滤器钩子失效及分页/标题缺失问题
问题根源分析
你的代码存在以下核心问题:
- 自定义
WP_Query未配置分页参数,默认仅返回10条产品 woocommerce_pagination()默认依赖全局$wp_query对象,无法识别自定义查询的分页数据- 归档标题、描述相关钩子依赖全局查询上下文,自定义查询下无法正常触发
- 复制
wc-template-hooks.php到子主题的操作无效,WooCommerce不支持以此方式覆盖钩子文件
具体修复步骤
1. 为自定义查询添加分页参数
在WP_Query的参数中加入分页配置,同时读取WooCommerce后台设置的每页产品数量:
// 获取当前页码(AJAX请求从POST获取) $paged = isset($_POST['paged']) ? absint($_POST['paged']) : 1; // 读取WooCommerce后台设置的每页产品数,默认12 $products_per_page = get_option('woocommerce_products_per_page', 12); $args = array( 'post_type' => 'product', 'posts_per_page' => $products_per_page, 'paged' => $paged, 'tax_query' => array( 'relation' => 'AND', ), );
2. 让分页函数识别自定义查询
临时将自定义查询对象赋值给全局$wp_query,确保woocommerce_pagination()能读取正确的分页数据:
// 临时替换全局查询对象 global $wp_query; $original_query = $wp_query; $wp_query = $products; // 输出分页 woocommerce_pagination(); // 恢复原始全局查询对象 $wp_query = $original_query;
3. 修复归档标题与描述显示
同样通过临时替换全局查询对象,让标题和描述钩子获取正确上下文:
// 临时替换全局查询对象 global $wp_query; $original_query = $wp_query; $wp_query = $products; ?> <header class="woocommerce-products-header"> <?php if ( apply_filters( 'woocommerce_show_page_title', true ) ) : ?> <h1 class="woocommerce-products-header__title page-title"><?php woocommerce_page_title(); ?></h1> <?php endif; ?> <?php do_action( 'woocommerce_archive_description' ); ?> </header> <?php // 恢复原始全局查询对象 $wp_query = $original_query;
4. 移除子主题中的wc-template-hooks.php文件
该文件是WooCommerce核心钩子定义文件,子主题无法通过复制覆盖修改,直接删除子主题中的这个文件即可。
修改后的完整代码
<?php add_action( 'wp_enqueue_scripts', 'my_theme_enqueue_styles' ); function my_theme_enqueue_styles() { wp_enqueue_style( 'parent-style', get_template_directory_uri() . '/style.css' ); } add_action( 'wp_ajax_filter_products', 'filter_products' ); add_action( 'wp_ajax_nopriv_filter_products', 'filter_products' ); function filter_products() { // 获取过滤参数 $styles = isset( $_POST['styles'] ) ? $_POST['styles'] : array(); $countries = isset( $_POST['country'] ) ? $_POST['country'] : array(); // 获取分页参数 $paged = isset($_POST['paged']) ? absint($_POST['paged']) : 1; $products_per_page = get_option('woocommerce_products_per_page', 12); $args = array( 'post_type' => 'product', 'posts_per_page' => $products_per_page, 'paged' => $paged, 'tax_query' => array( 'relation' => 'AND', ), ); if ( ! empty( $styles ) ) { $args['tax_query'][] = array( 'taxonomy' => 'styles', 'field' => 'slug', 'terms' => $styles, 'operator' => 'AND' ); } if ( ! empty( $countries ) ) { $args['tax_query'][] = array( 'taxonomy' => 'country', 'field' => 'slug', 'terms' => $countries, 'operator' => 'AND' ); } $products = new WP_Query( $args ); global $wp_query; $original_query = $wp_query; $wp_query = $products; if ( $products->have_posts() ) { // 输出标题和描述 ?> <header class="woocommerce-products-header"> <?php if ( apply_filters( 'woocommerce_show_page_title', true ) ) : ?> <h1 class="woocommerce-products-header__title page-title"><?php woocommerce_page_title(); ?></h1> <?php endif; ?> <?php do_action( 'woocommerce_archive_description' ); ?> </header> <?php // 输出通知、结果计数和排序 do_action( 'woocommerce_before_shop_loop' ); // 开始产品循环 woocommerce_product_loop_start(); // 遍历产品 while ( $products->have_posts() ) { $products->the_post(); do_action( 'woocommerce_shop_loop' ); wc_get_template_part( 'content', 'product' ); } // 结束产品循环 woocommerce_product_loop_end(); // 输出分页 woocommerce_pagination(); } else { // 无产品时输出提示 do_action( 'woocommerce_no_products_found' ); } // 恢复原始全局查询对象 $wp_query = $original_query; // 重置文章数据 wp_reset_postdata(); die(); }
内容的提问来源于stack exchange,提问作者KazuyaFirecracker
相关产品推荐
相关产品推荐

