如何定制无插件的WooCommerce不含指定成分商品内部搜索引擎?
WooCommerce 无插件成分反向搜索实现方案
一、是否需要创建自定义分类法(Taxonomy)?
推荐创建「商品成分」自定义分类法,原因如下:
- 比直接在商品描述中做模糊搜索更精准,查询性能更高
- 方便批量给商品打成分标签,后续维护和管理效率大幅提升
- 反向排除成分的逻辑实现更简洁、可靠
如果暂时不想投入精力做分类法,也可以直接基于商品描述实现,但数据量大时会有性能损耗,仅作为临时方案。
二、步骤1:注册商品成分自定义分类法
将以下代码添加到主题的functions.php文件中:
// 注册商品成分自定义分类法 function register_product_ingredient_taxonomy() { $args = array( 'labels' => array( 'name' => '商品成分', 'singular_name' => '成分', 'search_items' => '搜索成分', 'all_items' => '所有成分', 'edit_item' => '编辑成分', 'update_item' => '更新成分', 'add_new_item' => '添加新成分', 'new_item_name' => '新成分名称', 'menu_name' => '商品成分' ), 'public' => true, 'hierarchical' => false, // 非层级结构,如「糖」「麸质」等独立标签 'show_in_rest' => true, // 支持古腾堡编辑器 'show_admin_column' => true, // 在商品列表页显示成分列 ); register_taxonomy('product_ingredient', 'product', $args); } add_action('init', 'register_product_ingredient_taxonomy');
添加后,你可以在WooCommerce商品编辑页看到「商品成分」的标签管理区域,手动给商品添加对应成分即可。
三、步骤2:修改搜索表单
在现有搜索表单基础上,添加「排除该成分」的复选框,让用户选择正向搜索或反向排除:
<!-- 成分搜索表单 --> <form role="search" method="get" id="ingredient-search-form" action="<?php echo esc_url( home_url( '/' ) ); ?>"> <input type="hidden" name="post_type" value="product"> <input type="text" name="ingredient_search" placeholder="输入成分名称" value="<?php echo get_query_var('ingredient_search'); ?>"> <label> <input type="checkbox" name="exclude_ingredient" value="1" <?php checked(get_query_var('exclude_ingredient'), 1); ?>> 排除该成分 </label> <button type="submit">搜索商品</button> </form>
四、步骤3:实现pre_get_posts过滤逻辑
方案A:基于自定义分类法的高效搜索(推荐)
将以下代码添加到functions.php:
// 过滤产品查询,实现成分搜索/反向排除 function filter_product_by_ingredient($query) { // 仅在前台主查询、产品搜索场景生效 if (!is_admin() && $query->is_main_query() && isset($query->query_vars['post_type']) && $query->query_vars['post_type'] === 'product' && isset($_GET['ingredient_search'])) { $ingredient = sanitize_text_field($_GET['ingredient_search']); $is_exclude = isset($_GET['exclude_ingredient']) && $_GET['exclude_ingredient'] === '1'; // 匹配对应的成分分类 $term = get_term_by('name', $ingredient, 'product_ingredient'); if ($term && !is_wp_error($term)) { $tax_query = array( array( 'taxonomy' => 'product_ingredient', 'field' => 'term_id', 'terms' => $term->term_id, 'operator' => $is_exclude ? 'NOT IN' : 'IN' ) ); $query->set('tax_query', $tax_query); // 清空默认搜索关键词,避免干扰 $query->set('s', ''); } } } add_action('pre_get_posts', 'filter_product_by_ingredient');
方案B:基于商品描述的临时搜索(不推荐)
如果暂时不想用分类法,直接基于商品描述实现反向搜索,代码如下:
// 基于商品描述的成分反向搜索(性能较差,仅临时使用) function filter_product_by_description_ingredient($query) { if (!is_admin() && $query->is_main_query() && isset($query->query_vars['post_type']) && $query->query_vars['post_type'] === 'product' && isset($_GET['ingredient_search'])) { $ingredient = sanitize_text_field($_GET['ingredient_search']); $is_exclude = isset($_GET['exclude_ingredient']) && $_GET['exclude_ingredient'] === '1'; // 通过posts_where钩子过滤post_content add_filter('posts_where', function($where) use ($ingredient, $is_exclude) { global $wpdb; $operator = $is_exclude ? 'NOT LIKE' : 'LIKE'; $where .= $wpdb->prepare(" AND {$wpdb->posts}.post_content {$operator} %s", '%' . $wpdb->esc_like($ingredient) . '%'); return $where; }); // 清空默认搜索关键词 $query->set('s', ''); } } add_action('pre_get_posts', 'filter_product_by_description_ingredient');
五、注意事项
- 使用分类法方案时,需要手动给商品添加成分标签,也可以通过批量导入工具快速完成
- 基于商品描述的搜索会扫描所有商品的内容,商品数量较多时会影响页面加载速度
- 代码中已做参数安全过滤,避免SQL注入风险
内容的提问来源于stack exchange,提问作者Estudiante
相关产品推荐
相关产品推荐

