WooCommerce品牌分类层级展示需求:寻求有效实现方案
Hey there! Let's break down how to build this brand-category-product hierarchy in your custom Brands.php template, using WordPress and WooCommerce's native functions and hooks to keep things clean and maintainable.
1. First: Display Top-Level Brand Parent Categories
Assuming you're using a custom taxonomy for brands (common with plugins like YITH WooCommerce Brands, which uses yith_product_brand—replace this with your actual taxonomy slug if different), we'll fetch and display all top-level parent brands.
Add this to your Brands.php template:
<?php // Replace 'product_brand' with your brand taxonomy slug $parent_brands = get_terms([ 'taxonomy' => 'product_brand', 'parent' => 0, // Only fetch top-level parent brands 'hide_empty' => true, // Hide brands with no products 'orderby' => 'name', 'order' => 'ASC' ]); if (!empty($parent_brands) && !is_wp_error($parent_brands)) : ?> <section class="brand-parent-section"> <h2>Select a Brand</h2> <div class="brand-grid"> <?php foreach ($parent_brands as $brand) : ?> <a href="<?php echo esc_url(add_query_arg('brand_parent', $brand->term_id, get_permalink())); ?>" class="brand-card"> <?php echo esc_html($brand->name); ?> <!-- Optional: Display brand image if you have one stored as term meta --> <?php if ($brand_logo = get_term_meta($brand->term_id, 'brand_logo', true)) : ?> <img src="<?php echo esc_url($brand_logo); ?>" alt="<?php echo esc_attr($brand->name); ?> logo"> <?php endif; ?> </a> <?php endforeach; ?> </div> </section> <?php endif; ?>
2. Next: Show Child Product Categories for Selected Brand
When a user clicks a parent brand, we need to fetch all product categories (like AC, LCD, Refrigerator) that have products under that brand. We'll use the brand_parent query parameter to identify the selected brand.
Add this right after the parent brand section:
<?php // Check if a parent brand is selected via URL parameter if (isset($_GET['brand_parent']) && is_numeric($_GET['brand_parent'])) { $selected_brand_id = intval($_GET['brand_parent']); $selected_brand = get_term($selected_brand_id, 'product_brand'); // First, get all product IDs linked to this brand $brand_product_ids = get_posts([ 'post_type' => 'product', 'posts_per_page' => -1, 'fields' => 'ids', 'tax_query' => [ [ 'taxonomy' => 'product_brand', 'field' => 'term_id', 'terms' => $selected_brand_id ] ] ]); // Now fetch product categories associated with these products if (!empty($brand_product_ids)) { $child_product_cats = get_terms([ 'taxonomy' => 'product_cat', // WooCommerce's default product category taxonomy 'object_ids' => $brand_product_ids, 'hide_empty' => true, 'orderby' => 'name', 'order' => 'ASC' ]); if (!empty($child_product_cats) && !is_wp_error($child_product_cats)) : ?> <section class="child-cat-section"> <h3>Categories for <?php echo esc_html($selected_brand->name); ?></h3> <div class="cat-grid"> <?php foreach ($child_product_cats as $cat) : ?> <a href="<?php echo esc_url(add_query_arg([ 'brand_parent' => $selected_brand_id, 'brand_child' => $cat->term_id ], get_permalink())); ?>" class="cat-card"> <?php echo esc_html($cat->name); ?> </a> <?php endforeach; ?> </div> </section> <?php endif; } else { echo "<p>No products found for {$selected_brand->name}.</p>"; } } ?>
3. Finally: Display Products with WooCommerce Store Layout
To match WooCommerce's native store styling, we'll modify the main query using the pre_get_posts hook, then use WooCommerce's built-in loop functions to render the products.
Step 3.1: Add the Query Filter to functions.php
This tells WordPress to fetch the right products when both brand_parent and brand_child parameters are present:
add_action('pre_get_posts', 'filter_brand_category_products'); function filter_brand_category_products($query) { // Only modify the front-end main query on your Brands template if (!is_admin() && $query->is_main_query() && is_page_template('Brands.php')) { if (isset($_GET['brand_parent']) && isset($_GET['brand_child']) && is_numeric($_GET['brand_parent']) && is_numeric($_GET['brand_child'])) { $brand_id = intval($_GET['brand_parent']); $cat_id = intval($_GET['brand_child']); // Set up tax query to filter by both brand and product category $query->set('post_type', 'product'); $query->set('tax_query', [ 'relation' => 'AND', [ 'taxonomy' => 'product_brand', 'field' => 'term_id', 'terms' => $brand_id ], [ 'taxonomy' => 'product_cat', 'field' => 'term_id', 'terms' => $cat_id ] ]); // Match your store's products per page setting $query->set('posts_per_page', get_option('posts_per_page')); } } }
Step 3.2: Render the Product Loop in Brands.php
Add this at the end of your template to display products with WooCommerce's default layout:
<?php // Only show product loop if a child category is selected if (isset($_GET['brand_child']) && is_numeric($_GET['brand_child'])) { $selected_cat = get_term(intval($_GET['brand_child']), 'product_cat'); $selected_brand = get_term(intval($_GET['brand_parent']), 'product_brand'); ?> <section class="products-section"> <h3><?php echo esc_html($selected_brand->name); ?> - <?php echo esc_html($selected_cat->name); ?></h3> <?php // Start WooCommerce product loop (matches your store's layout) woocommerce_product_loop_start(); if (have_posts()) : while (have_posts()) : the_post(); // Use WooCommerce's native product template part wc_get_template_part('content', 'product'); endwhile; else : echo '<p>No products found in this category.</p>'; endif; woocommerce_product_loop_end(); // Add WooCommerce's default pagination woocommerce_pagination(); ?> </section> <?php } ?>
Bonus: Ensure WooCommerce Styles Load
To make sure the product loop matches your store's styling, add this to functions.php to load WooCommerce styles on your Brands template:
add_action('wp_enqueue_scripts', 'load_woocommerce_styles_for_brands'); function load_woocommerce_styles_for_brands() { if (is_page_template('Brands.php')) { wp_enqueue_style('woocommerce'); wp_enqueue_style('woocommerce-layout'); wp_enqueue_style('woocommerce-smallscreen'); } }
Key Notes:
- Replace
product_brandwith your actual brand taxonomy slug (check your brand plugin's settings if using one). - Adjust HTML classes like
brand-gridorcat-cardto match your theme's styling system. - For SEO-friendly URLs, you can add custom rewrite rules later to replace query parameters with clean slugs (e.g.,
/brands/samsung/air-conditioner/), but the above code works perfectly as a starting point.
内容的提问来源于stack exchange,提问作者syed immad




