Woocommerce+Polylang:AJAX请求非默认语言商品不显示问题
WooCommerce + Polylang 多语言商品筛选故障修复
我有一个基于WordPress的站点,搭载WooCommerce和Polylang插件,需要实现按类别筛选商品的功能。默认语言下一切正常,但切换到非默认语言时,商品完全无法显示。每种语言对应独立的商品集合,非默认语言下甚至通不过帖子存在性检查。
原问题代码
$categories = $_POST['categories']; $categories_lang = $_POST['language']; $product_category_slug_aa; $product_category_slug_employees; if ($categories_lang == 'ru') { $product_category_slug_aa = "course_base"; $product_category_slug_employees = "employees"; } else if ($categories_lang == 'en'){ $product_category_slug_aa = "course_base"; $product_category_slug_employees = "employees"; } else if ($categories_lang == 'nb'){ $product_category_slug_aa = "course_base-nb"; $product_category_slug_employees = "employees-nb"; } $args = array( 'post_type' => 'product', 'posts_per_page' => 20, 'tax_query' => array( 'relation' => 'AND', array( 'taxonomy' => 'product_cat', 'field' => 'slug', 'terms' => $categories_lang, ), array( 'taxonomy' => 'product_cat', 'field' => 'slug', 'terms' => $product_category_slug_aa, 'operator' => 'NOT IN', ), array( 'taxonomy' => 'product_cat', 'field' => 'slug', 'terms' => $product_category_slug_employees, 'operator' => 'NOT IN', ), ), ); if (!empty($categories)) { $tax_queries = array(); foreach ($categories as $category) { $tax_queries[] = array( 'taxonomy' => 'product_cat', 'field' => 'slug', 'terms' => $category, ); } $args['tax_query'] = array_merge($args['tax_query'], $tax_queries); } $query = new WP_Query($args); if ($query->have_posts()) { while ($query->have_posts()) { $query->the_post(); $terms = get_the_terms(get_the_ID(), 'product_cat'); if ($terms && !is_wp_error($terms)) { $courses_found = false; foreach ($terms as $term) { if ($term->slug === 'courses' || $term->slug === 'courses-nb') { $courses_found = true; } } if ($courses_found) { wc_get_template_part('content', 'product-courses'); } } } }
问题根源
- 错误的语言筛选逻辑:把语言标识(如
nb)直接当作商品分类slug查询,Polylang根本不是用这种方式区分多语言内容的。 - 硬编码多语言分类slug:手动判断语言写slug不仅冗余,还容易遗漏或写错,Polylang有内置函数可以自动匹配对应语言的分类。
- 查询条件冲突:默认
tax_query用了AND关系,后续合并用户分类时没处理关系,导致条件矛盾。 - 冗余的二次过滤:循环里手动检查
courses分类,完全可以整合到初始查询参数里,浪费性能。
修复后的代码
<?php $categories = $_POST['categories']; $selected_lang = $_POST['language']; // 强制设置当前查询的语言上下文 pll_current_language($selected_lang); // 通过Polylang自动获取对应语言的排除分类 $course_base_term = pll_get_term_by('slug', 'course_base', 'product_cat', $selected_lang); $employees_term = pll_get_term_by('slug', 'employees', 'product_cat', $selected_lang); $tax_query = array( 'relation' => 'AND', // 排除指定分类 array( 'taxonomy' => 'product_cat', 'field' => 'term_id', 'terms' => $course_base_term ? $course_base_term->term_id : array(), 'operator' => 'NOT IN', ), array( 'taxonomy' => 'product_cat', 'field' => 'term_id', 'terms' => $employees_term ? $employees_term->term_id : array(), 'operator' => 'NOT IN', ), // 直接筛选courses分类的商品(自动匹配对应语言) array( 'taxonomy' => 'product_cat', 'field' => 'slug', 'terms' => pll_translate_string('courses', $selected_lang), ) ); // 处理用户选择的分类筛选 if (!empty($categories)) { $user_tax_queries = array(); foreach ($categories as $category_slug) { // 获取对应语言的分类ID $term = pll_get_term_by('slug', $category_slug, 'product_cat', $selected_lang); if ($term) { $user_tax_queries[] = array( 'taxonomy' => 'product_cat', 'field' => 'term_id', 'terms' => $term->term_id, ); } } // 合并用户分类条件(此处用OR,需AND可自行修改) if (!empty($user_tax_queries)) { $tax_query[] = array( 'relation' => 'OR', ...$user_tax_queries ); } } $args = array( 'post_type' => 'product', 'posts_per_page' => 20, 'tax_query' => $tax_query, // 让Polylang自动过滤当前语言的商品 'lang' => $selected_lang, ); $query = new WP_Query($args); if ($query->have_posts()) { while ($query->have_posts()) { $query->the_post(); wc_get_template_part('content', 'product-courses'); } wp_reset_postdata(); } ?>
关键修复说明
- 正确关联多语言上下文:用
pll_current_language()和'lang' => $selected_lang让Polylang自动过滤对应语言的商品,不用自己瞎凑条件。 - 用Polylang函数匹配分类:
pll_get_term_by()和pll_translate_string()自动适配多语言分类,告别硬编码。 - 简化查询逻辑:把courses分类检查整合到初始查询,去掉冗余循环。
- 避免条件冲突:用户分类用OR关系(可按需改AND),确保查询逻辑通顺。
- 安全处理空值:添加判断确保分类有效后再加入查询,防止报错。
内容的提问来源于stack exchange,提问作者Максим Ильенко
相关产品推荐
相关产品推荐

