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

如何在WooCommerce中关联类别与属性术语以创建头部菜单

关联WooCommerce产品分类与属性术语的解决方案

针对你需要构建的层级头部菜单需求,我整理了两种可行的方案,帮你把产品分类(父子层级)和对应的属性术语关联起来,直接就能用到你的项目里:

核心逻辑说明

WooCommerce里,产品分类(product_cat)和属性术语(pa_xxx类型的 taxonomy)都存在wp_terms表中,两者通过产品作为中间关联层:每个产品既属于某个分类,又关联了对应的属性术语,所以我们可以通过产品ID(object_id)把分类和属性术语连接起来。


方案一:直接SQL查询(适合快速获取数据的场景)

如果你需要直接从数据库拉取某个子分类下的所有属性术语,这个去重后的查询很实用,只会返回该分类下产品实际用到的属性术语:

SELECT DISTINCT t.term_id, t.name, t.slug, tt.taxonomy
FROM wp_terms t
JOIN wp_term_taxonomy tt ON t.term_id = tt.term_id
JOIN wp_term_relationships tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
JOIN wp_term_relationships tr_cat ON tr.object_id = tr_cat.object_id
JOIN wp_term_taxonomy tt_cat ON tr_cat.term_taxonomy_id = tt_cat.term_taxonomy_id
WHERE tt.taxonomy LIKE 'pa_%' -- 只筛选属性类型的术语
AND tt_cat.taxonomy = 'product_cat' -- 锁定产品分类
AND tt_cat.term_id = 123 -- 替换成你的子分类ID
ORDER BY tt.taxonomy, t.name; -- 按属性分组排序

查询解释

  • 通过wp_term_relationships关联产品ID,把分类和属性术语绑定到同一个产品上
  • DISTINCT确保同一个属性术语不会重复出现
  • 最后按属性类型(比如pa_wattage)和术语名称排序,方便后续整理成菜单

方案二:WooCommerce内置PHP函数(适合主题/插件开发,更安全)

如果你是在WordPress主题里开发菜单,推荐用WooCommerce官方函数,避免直接操作数据库带来的兼容性问题。下面是完整的层级菜单构建代码:

第一步:封装获取子分类属性术语的函数

/**
 * 获取指定子分类下所有产品关联的属性术语
 * @param int $child_cat_id 子分类ID
 * @return array 按属性分组的术语列表
 */
function get_child_category_attribute_terms($child_cat_id) {
    // 获取子分类下的所有已发布产品(-1表示获取全部)
    $products = wc_get_products(array(
        'category' => array(get_term($child_cat_id)->slug),
        'limit' => -1,
        'status' => 'publish'
    ));

    $attribute_terms = array();

    foreach ($products as $product) {
        // 获取产品的所有属性
        $attributes = $product->get_attributes();
        foreach ($attributes as $attribute) {
            // 跳过自定义属性(如果需要包含自定义属性,可注释这一行)
            if (!$attribute->is_taxonomy()) continue;

            $taxonomy = $attribute->get_taxonomy();
            // 获取产品关联的属性术语ID列表
            $term_ids = $product->get_attribute($taxonomy);
            if (empty($term_ids)) continue;

            // 获取术语对象
            $term_objects = get_terms(array(
                'taxonomy' => $taxonomy,
                'include' => explode(',', $term_ids),
                'hide_empty' => false
            ));

            // 去重存储术语
            foreach ($term_objects as $term) {
                $attribute_terms[$taxonomy][$term->term_id] = $term;
            }
        }
    }

    return $attribute_terms;
}

第二步:构建完整的层级菜单

// 获取所有一级产品分类(parent为0的分类)
$parent_categories = get_terms(array(
    'taxonomy' => 'product_cat',
    'parent' => 0,
    'hide_empty' => true, // 只显示有产品的分类,可选
    'orderby' => 'name'
));

// 遍历一级分类构建菜单
foreach ($parent_categories as $parent_cat) {
    echo '<div class="menu-level-1">';
    echo '<h2>' . esc_html($parent_cat->name) . '</h2>';

    // 获取当前一级分类的子分类
    $child_categories = get_terms(array(
        'taxonomy' => 'product_cat',
        'parent' => $parent_cat->term_id,
        'hide_empty' => true,
        'orderby' => 'name'
    ));

    // 遍历子分类
    foreach ($child_categories as $child_cat) {
        echo '<div class="menu-level-2">';
        echo '<h3>' . esc_html($child_cat->name) . '</h3>';

        // 商城链接:跳转到子分类产品列表页
        $shop_link = get_term_link($child_cat);
        echo '<a href="' . esc_url($shop_link) . '" class="shop-link">商城</a>';

        // 获取该子分类下的属性术语
        $attribute_terms = get_child_category_attribute_terms($child_cat->term_id);

        // 构建属性术语菜单
        echo '<div class="menu-level-3">';
        foreach ($attribute_terms as $taxonomy => $terms) {
            // 去掉属性taxonomy的pa_前缀,显示友好名称
            $attr_name = str_replace('pa_', '', $taxonomy);
            echo '<div class="attribute-group">';
            echo '<span class="attribute-name">' . esc_html($attr_name) . '</span>';
            echo '<ul class="attribute-terms">';
            
            foreach ($terms as $term) {
                // 构建筛选链接:子分类+属性术语的产品列表
                $filtered_link = add_query_arg(array(
                    'product_cat' => $child_cat->slug,
                    $taxonomy => $term->slug
                ), home_url('/shop/'));
                
                echo '<li><a href="' . esc_url($filtered_link) . '">' . esc_html($term->name) . '</a></li>';
            }
            
            echo '</ul>';
            echo '</div>';
        }
        echo '</div>';

        echo '</div>';
    }

    echo '</div>';
}

代码说明

  • 自动按「一级分类→子分类→属性术语」的层级构建菜单
  • 每个属性术语的链接会自动筛选出该子分类下对应术语的产品
  • 用esc_html和esc_url确保输出内容安全,避免XSS漏洞
  • 可以通过CSS类(menu-level-1、menu-level-2等)自定义菜单样式

优化建议

  1. 缓存优化:如果分类下产品很多,每次加载都查询产品会影响性能,建议用WordPress的缓存函数缓存属性术语结果:
    $cache_key = 'cat_attr_terms_' . $child_cat_id;
    $attribute_terms = wp_cache_get($cache_key);
    if (!$attribute_terms) {
        $attribute_terms = get_child_category_attribute_terms($child_cat_id);
        wp_cache_set($cache_key, $attribute_terms, '', 3600); // 缓存1小时
    }
    
  2. 自定义属性支持:如果需要包含自定义属性(非 taxonomy 类型),可以修改函数,用$attribute->get_options()获取自定义属性的值。
  3. 性能优化:如果子分类下产品数量极大,建议用方案一的SQL查询代替wc_get_products,减少内存占用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:31:38