WordPress / 10 MIN READ
Child Categories from Attributes
Creating WooCommerce categories, then creating child categories from values of custom fields with PHP
From the original Fervor library. Examples may use older package versions.
“Mastering Product Organization: Creating Child Categories for Custom Product Attributes in WooCommerce”
Organizing your WooCommerce store based on specific product attributes, like custom ranges or properties, can significantly improve your customers’ shopping experience. Whether you’re categorizing products by wavelength, size, price range, or any other attribute, the principles remain the same.
This tutorial uses wavelength as an example to demonstrate how to create a parent category and child categories programmatically and dynamically assign products to these categories based on custom attribute values. Let’s focus on the concept so you can adapt it to any scenario.
Overview of What We’ll Achieve
Imagine your store sells products with measurable properties—like wavelength, weight, power, or dimensions. Instead of overwhelming your customers with a long product list, you can create a structured hierarchy like this:
- Parent Category: Product Attributes
- Child Categories:
- Range 1 (200–500 units)
- Range 2 (500–900 units)
- Child Categories:
By replacing wavelength with your specific property, you can extend this method to any measurable or categorical attribute.
Step 1: Create a Parent Category for the Attribute
Why This Step Is Important
A parent category provides a top-level organization for the child categories. For example, “Product Attributes” or “Wavelengths” serves as a logical grouping for related subcategories.
Code Example: Adding the Parent Category
Add this to your theme’s functions.php file or custom plugin:
function create_parent_attribute_category() {
// Check if the parent category already exists
if (!term_exists('Product Attributes', 'product_cat')) {
wp_insert_term(
'Product Attributes', // Name of the parent category
'product_cat', // Taxonomy slug for WooCommerce categories
array(
'description' => 'Products grouped by custom attribute ranges.',
'slug' => 'product-attributes', // Custom URL-friendly slug
'parent' => 0, // 0 indicates no parent (top-level category)
)
);
}
}
add_action('init', 'create_parent_attribute_category');
Explanation of the Code:
- Concept: Replace “Product Attributes” with the name of your primary grouping (e.g., “Power Levels,” “Dimensions,” etc.).
- Key Functionality:
term_exists()ensures the category isn’t duplicated.wp_insert_term()creates the parent category.parent => 0specifies that this is a top-level category.
Step 2: Create Child Categories for Ranges
Why This Step Is Important
Child categories allow you to break down the attribute into smaller, meaningful segments. For instance:
- Products between 200–500 units can go into one category.
- Products between 500–900 units can go into another.
Code Example: Adding Child Categories
Add this code to create child categories under the parent category:
function create_attribute_child_categories() {
// Fetch the parent category ID
$parent_category = get_term_by('slug', 'product-attributes', 'product_cat');
if ($parent_category) {
$parent_id = $parent_category->term_id;
// Define child categories and their properties
$child_categories = array(
'Range 1 (200-500 units)' => '200-500-units',
'Range 2 (500-900 units)' => '500-900-units',
);
foreach ($child_categories as $name => $slug) {
if (!term_exists($name, 'product_cat')) {
wp_insert_term(
$name, // Name of the child category
'product_cat', // Taxonomy
array(
'description' => "Products with attributes in $name.",
'slug' => $slug, // URL slug
'parent' => $parent_id, // Assign to the parent category
)
);
}
}
}
}
add_action('init', 'create_attribute_child_categories');
Explanation of the Code:
- Concept: Replace “Range 1 (200-500 units)” and “Range 2 (500-900 units)” with the ranges or values relevant to your attribute.
- Key Functionality:
get_term_by()fetches the parent category by its slug (product-attributes).wp_insert_term()creates child categories with descriptions and assigns them to the parent.
Step 3: Assign Products to Child Categories Dynamically
Why This Step Is Important
Manually assigning products is impractical for large inventories. Automating the process ensures accurate categorization based on the product’s attribute value.
Code Example: Assigning Products to Child Categories
Add this function to dynamically assign products:
function assign_products_to_attribute_categories() {
// Example: Replace '_attribute_value' with your actual custom field key
$meta_key = '_attribute_value';
// Fetch all products with the attribute
$products = wc_get_products(array(
'limit' => -1, // Get all products
'meta_key' => $meta_key, // Filter products with this meta field
'meta_compare' => 'EXISTS',
));
foreach ($products as $product) {
$product_id = $product->get_id();
$attribute_value = get_post_meta($product_id, $meta_key, true);
// Assign to the correct category based on attribute value
if ($attribute_value >= 200 && $attribute_value <= 500) {
wp_set_object_terms($product_id, '200-500-units', 'product_cat', true);
} elseif ($attribute_value > 500 && $attribute_value <= 900) {
wp_set_object_terms($product_id, '500-900-units', 'product_cat', true);
}
}
}
add_action('init', 'assign_products_to_attribute_categories');
Explanation of the Code:
- Concept: Replace
_attribute_valuewith the meta key for your product’s custom field. - Key Functionality:
wc_get_products()fetches all products with a specific meta field.get_post_meta()retrieves the product’s attribute value.wp_set_object_terms()assigns the product to the correct child category based on its value.
Step 4: Verify and Display the Category Hierarchy
How to Check the Categories:
- Go to Products > Categories in your WordPress dashboard.
- Verify that:
- The parent category (“Product Attributes”) exists.
- The child categories (“200-500 units,” “500-900 units”) exist under the parent.
Display the Categories on the Shop Page:
You can use a shortcode or modify the product archive template to display the categories dynamically.
Example: Display Categories with Shortcode
Use the following shortcode to display all child categories under “Product Attributes”:
[product_categories parent="product-attributes"]
Example: Customize Category Display with PHP
To group products by categories dynamically, use this in your archive-product.php file:
function display_custom_attribute_categories() {
$categories = get_terms(array(
'taxonomy' => 'product_cat',
'parent' => get_term_by('slug', 'product-attributes', 'product_cat')->term_id,
'hide_empty' => true,
));
if (!empty($categories)) {
echo '<ul class="attribute-categories">';
foreach ($categories as $category) {
echo '<li>';
echo '<a href="' . esc_url(get_term_link($category)) . '">' . esc_html($category->name) . '</a>';
echo '</li>';
}
echo '</ul>';
}
}
add_action('woocommerce_before_shop_loop', 'display_custom_attribute_categories');
Step 5: Test the Implementation
- Add Attribute Values:
- Ensure products have meta values for the custom field (e.g.,
_attribute_value).
- Ensure products have meta values for the custom field (e.g.,
- Run the Functions:
- Reload your site to trigger the category creation and product assignment functions.
- Verify the Display:
- Check your store’s front end to ensure products appear in the correct categories.
Conclusion
With this method, you’ve created a flexible, scalable solution to categorize WooCommerce products by any attribute. Whether it’s wavelength, price range, weight, or any other property, this approach allows you to streamline navigation and improve the customer experience.
BONUS ADVANCED TUTORIAL
“Advanced Product Organization: Filtering WooCommerce Products by Multiple Fields for Parent and Child Categories”
Organizing WooCommerce products with multiple specific fields tied to parent categories allows for tailored filters and easier navigation. In this tutorial, we’ll explore how to dynamically assign products to child categories based on attributes specific to their parent category.
We’ll use two examples:
- Bandpass Filters categorized by wavelength ranges.
- Mirrors categorized by mirror types (e.g., hot or cold).
This setup can be extended to any combination of parent categories and their specific filters.
Overview of What We’ll Achieve
Structure:
-
Parent Categories:
- Bandpass Filters
- Child Categories: 200–500nm, 501–700nm, 701–900nm
- Mirrors
- Child Categories: Hot Mirrors, Cold Mirrors
- Bandpass Filters
-
Products will be dynamically assigned to child categories based on custom fields:
- Bandpass Filters will use the
wave_lengthfield. - Mirrors will use the
mirror_typefield.
- Bandpass Filters will use the
Step 1: Create Parent Categories
We’ll create two parent categories: Bandpass Filters and Mirrors.
Code to Create Parent Categories
Add this to your theme’s functions.php file or custom plugin:
function create_parent_categories() {
$parent_categories = array(
'Bandpass Filters' => 'bandpass-filters',
'Mirrors' => 'mirrors',
);
foreach ($parent_categories as $name => $slug) {
if (!term_exists($name, 'product_cat')) {
wp_insert_term(
$name,
'product_cat',
array(
'description' => "Parent category for $name.",
'slug' => $slug,
'parent' => 0, // Top-level category
)
);
}
}
}
add_action('init', 'create_parent_categories');
Explanation:
$parent_categories: An array defines the names and slugs of parent categories.term_exists(): Ensures duplicate categories are not created.wp_insert_term(): Adds parent categories to WooCommerce.
Step 2: Create Child Categories Specific to Each Parent
We’ll now create child categories for each parent category with their corresponding filters.
Code to Create Child Categories
Add this to your functions.php file or custom plugin:
function create_child_categories_for_parents() {
// Define child categories for each parent
$child_categories = array(
'bandpass-filters' => array(
'200-500nm' => '200-500nm',
'501-700nm' => '501-700nm',
'701-900nm' => '701-900nm',
),
'mirrors' => array(
'Hot Mirrors' => 'hot-mirrors',
'Cold Mirrors' => 'cold-mirrors',
),
);
foreach ($child_categories as $parent_slug => $children) {
$parent_term = get_term_by('slug', $parent_slug, 'product_cat');
if ($parent_term) {
$parent_id = $parent_term->term_id;
foreach ($children as $child_name => $child_slug) {
if (!term_exists($child_name, 'product_cat')) {
wp_insert_term(
$child_name,
'product_cat',
array(
'description' => "Products for $child_name.",
'slug' => $child_slug,
'parent' => $parent_id, // Assign to the parent category
)
);
}
}
}
}
}
add_action('init', 'create_child_categories_for_parents');
Explanation:
$child_categories: Defines child categories for each parent (e.g., wavelength ranges for Bandpass Filters, types for Mirrors).get_term_by(): Fetches the parent category by its slug.wp_insert_term(): Creates child categories and assigns them to their parent.
Step 3: Assign Products to Child Categories Based on Specific Fields
Why This Step Is Important
Products should automatically be categorized based on the relevant field (e.g., wave_length for Bandpass Filters, mirror_type for Mirrors).
Code to Assign Products Dynamically
Add this to your functions.php file or custom plugin:
function assign_products_to_child_categories() {
// Define field-to-category mapping
$field_to_category = array(
'wave_length' => array(
'200-500nm' => array(200, 500),
'501-700nm' => array(501, 700),
'701-900nm' => array(701, 900),
),
'mirror_type' => array(
'hot-mirrors' => 'hot',
'cold-mirrors' => 'cold',
),
);
// Fetch all products
$products = wc_get_products(array(
'limit' => -1, // Fetch all products
));
foreach ($products as $product) {
$product_id = $product->get_id();
foreach ($field_to_category as $field => $categories) {
$field_value = get_post_meta($product_id, "_$field", true);
foreach ($categories as $category_slug => $condition) {
if ($field === 'wave_length' && is_array($condition)) {
// Check if wave_length is within range
if ($field_value >= $condition[0] && $field_value <= $condition[1]) {
wp_set_object_terms($product_id, $category_slug, 'product_cat', true);
}
} elseif ($field === 'mirror_type' && $field_value === $condition) {
// Assign based on mirror_type
wp_set_object_terms($product_id, $category_slug, 'product_cat', true);
}
}
}
}
}
add_action('init', 'assign_products_to_child_categories');
Explanation:
$field_to_category:- Maps custom fields (
wave_length,mirror_type) to child categories. - For wave_length, uses a range (e.g., 200–500).
- For mirror_type, uses exact matches (e.g., “hot”).
- Maps custom fields (
wc_get_products(): Fetches all products.get_post_meta(): Retrieves custom field values for each product.wp_set_object_terms(): Assigns products to the corresponding child category.
Step 4: Verify and Display the Categories
Verify in Admin:
-
Go to Products > Categories to ensure:
- Bandpass Filters and Mirrors exist as parent categories.
- Their child categories (e.g., 200–500nm, Hot Mirrors) are correctly nested.
-
Check products in the WooCommerce product editor to ensure they’re assigned to the correct child categories.
Display Categories on the Front End:
WooCommerce will automatically display categories on your shop page if your theme supports it. To explicitly display categories:
Shortcode for Specific Parent Categories
Use the following shortcode to show child categories for a specific parent:
[product_categories parent="bandpass-filters"]
[product_categories parent="mirrors"]
Custom Code to Group Categories on the Shop Page
You can dynamically display parent and child categories in your archive-product.php file:
function display_parent_and_child_categories() {
$parents = array('bandpass-filters', 'mirrors');
foreach ($parents as $parent_slug) {
$parent = get_term_by('slug', $parent_slug, 'product_cat');
if ($parent) {
echo '<h2>' . esc_html($parent->name) . '</h2>';
$child_categories = get_terms(array(
'taxonomy' => 'product_cat',
'parent' => $parent->term_id,
'hide_empty' => true,
));
if (!empty($child_categories)) {
echo '<ul>';
foreach ($child_categories as $child) {
echo '<li>';
echo '<a href="' . esc_url(get_term_link($child)) . '">' . esc_html($child->name) . '</a>';
echo '</li>';
}
echo '</ul>';
}
}
}
}
add_action('woocommerce_before_shop_loop', 'display_parent_and_child_categories');
Testing the Setup
- Add Custom Fields:
- Use the product editor to add
wave_lengthandmirror_typevalues to products.
- Use the product editor to add
- Run the Functions:
- Reload the site to execute the scripts.
- Check Assignments:
- Verify that products are correctly categorized in Products > Categories.
Conclusion
This advanced tutorial shows how to:
- Organize products under parent and child categories based on custom fields.
- Dynamically assign products to categories based on specific conditions.
By applying this flexible system, you can create a tailored shopping experience for your customers, whether you’re categorizing by wavelength, mirror types, or any other attribute.