You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将自定义产品属性筛选条件传入WP_Query实现分类过滤?

WooCommerce产品分类页属性筛选实现问题

注:已编辑,我已将功能转为表单并使用GET方法。

这是我首次在此提问,请多包涵。我是WordPress/WooCommerce主题开发新手,正全力以赴完成开发。

此主题专为我自己的网站打造,编写的Ccon_Catalog_Filters类旨在在产品分类页展示基于产品属性的复选框筛选选项。目前通过上百次谷歌搜索,我已完成该类编写,并在functions.php中使用require_once引入类文件。

此类会生成可滚动的复选框列表用于筛选分类结果。现在我已将筛选参数存入$_GET全局变量,但卡在如何将参数传入WP_Query实现结果过滤:

  • 不确定是否需要复制Woocommerce的taxonomy-product-cat.php模板自定义查询循环
  • 不清楚如何让「应用筛选」按钮触发新查询
  • 需实现同一复选框组内OR、不同组间AND的逻辑

查阅pre_get_posts钩子文档后仍迷茫,拆解同类插件也未获思路,恳请指引方向。

<?php 

if (!class_exists('Ccon_Catalog_filters')) {
    class Ccon_Catalog_Filters {
        function init() {
            add_action( 'woocommerce_archive_description', [ $this, 'category_filter_menu'], 9, 1);
            add_action( 'product_cat_edit_form_fields', [ $this, 'taxonomy_edit_meta_field' ], 10, 1);
            add_action( 'edited_product_cat', [ $this, 'save_taxonomy_custom_meta' ], 10, 1);
            
        }
        function category_filter_menu() {
            $filters = $this->get_filter_options();
            $this->status($filters);
            echo var_dump($_GET);
            ?>
                <form method="GET" class="archive-filter-container">
                    <?php foreach ($filters as $filter): ?>
                        <?php $terms = $this->get_filter_att_val($filter); ?>
                        <div class="archive-filter-item archive-filter-item-<?php echo esc_attr($filter->attribute_name); ?>">
                            <h4><?php echo $filter->attribute_label; ?></h4>
                            <div class="archive-filter-content">
                                <?php foreach ($terms as $term): ?>
                                    <div style="display: block">
                                        <input 
                                            type=   "checkbox" 
                                            name=   "<?php echo esc_attr($filter->attribute_name); ?>[]" 
                                            id=     "<?php echo esc_attr($filter->attribute_name . '-' . $term->slug); ?>"
                                            value=  "<?php echo esc_attr($term->slug); ?>"
                                            <?php $this->checked($term, $filter); ?>
                                        >
                                        <label for="<?php echo esc_attr($filter->attribute_name . '-' . $term->slug); ?>">
                                            <?php echo esc_html($term->name); ?>
                                        </label>
                                    </div>
                                <?php endforeach; ?>
                            </div>
                        </div>
                    <?php endforeach; ?>
                    <button type="submit" value="apply" class="button" name="filteraction" >Apply Filters</button> 
                </form>
            <?php
        }
        function status($filters) {
            if (isset($_GET['filteraction'])) {
                if ($_GET['filteraction'] == 'apply') {
                    echo 'Filters Applied';
                } else {
                    echo 'Invalid action';
                }
            } else {
                echo 'Choose a filter:';
            }
        }

        function checked($term, $filter) {
            $arr_name = isset($_GET[$filter->attribute_name]) ? $_GET[$filter->attribute_name] : [];
            $check = in_array($term->slug, $arr_name);
            $checked = checked( $check, true );
            return $checked;
        }

        function get_filter_options() {
            $term_id = get_queried_object()->term_id;
            $checked_att_ids_raw = get_term_meta($term_id, 'checked_atts');
            $checked_att_ids = array_pop( $checked_att_ids_raw ) ?: [];
            $all_atts = wc_get_attribute_taxonomies();

            $filteratt = [];
            foreach ( $checked_att_ids as $index=>$att_id ) {
                $filteratt[$index] = $all_atts['id:' . $checked_att_ids[$index]];
            }
            return $filteratt; 
        }
        function get_filter_att_val($values) {
            $term_names = get_terms( [
                'taxonomy'  => 'pa_' . $values->attribute_name, 
                'fields'    => 'all', 
            ] );
            return $term_names;
        }
        //Product Cat Edit page
        function taxonomy_edit_meta_field($term) {
            //getting term ID
            $term_id = $term->term_id;
            $all_atts = wc_get_attribute_taxonomies();
            $checked_att_ids_raw = get_term_meta($term_id, 'checked_atts');
            $checked_att_ids = array_pop( $checked_att_ids_raw ) ?: [];
            ?>
                <tr class="form-field">
                    <th scope="row" valign="top"><label for="att_list"><?php _e('Filter by Attribute', 'wh'); ?></label></th>
                    <td>
                        <div style="height: 150px; overflow-y: scroll; background-color: white; padding: 8px;">
                            <?php foreach( $all_atts as $key => $attribute ): ?>
                                <div style="display: block">
                                    <input 
                                        type=   "checkbox" 
                                        name=   "att_list_items[]" 
                                        id=     "<?php echo esc_attr($attribute->attribute_name); ?>"
                                        value=  "<?php echo esc_attr($attribute->attribute_id);?>"
                                        <?php checked( in_array( $attribute->attribute_id, $checked_att_ids ), true ) ?>
                                    >
                                    <label 
                                        for="<?php echo esc_attr($attribute->attribute_name); ?>" >
                                        <?php echo esc_attr($attribute->attribute_label); ?>
                                    </label>
                                </div>
                            <?php endforeach; ?>
                        </div>
                        <p class="description">Please select which attributes you would like to filter from</p>
                    </td>
                </tr>
            <?php
        }
        function save_taxonomy_custom_meta($term_id) {
            $wh_meta_title = $_POST['att_list_items'];
            update_term_meta($term_id, 'checked_atts', $wh_meta_title);
        }
    }             
    ($ccon_catalog_filters = new Ccon_Catalog_Filters)->init();
}

我尝试下载同类插件拆解参考,但因逻辑复杂未获得有效思路。


内容的提问来源于stack exchange,提问作者HighTechLab

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 09:57:33