WordPress / 10 MIN READ
Woo Category Sorting PHP
Sorting WooCommerce products by category
From the original Fervor library. Examples may use older package versions.
Yes, you can sort and organize products into categories programmatically in WooCommerce. WooCommerce uses the product_cat taxonomy for categories, and you can create, sort, and assign products to categories dynamically using custom code.
Here’s How to Sort and Create Categories Programmatically:
1. Programmatically Create Categories
You can use the wp_insert_term function to create categories if they don’t already exist. Here’s an example:
function create_product_categories() {
$categories = [
'Electronics',
'Filters',
'Lenses',
'Bandpass Filters',
'Infrared Filters'
];
foreach ($categories as $category) {
// Check if the category already exists
if (!term_exists($category, 'product_cat')) {
wp_insert_term(
$category, // The category name
'product_cat', // Taxonomy
[
'description' => $category . ' category',
'slug' => sanitize_title($category)
]
);
}
}
}
add_action('init', 'create_product_categories');
2. Assign Products to Categories Programmatically
You can assign products to categories using the wp_set_object_terms function.
function assign_products_to_categories() {
// Define products and their categories
$products = [
[
'product_id' => 123, // Replace with your product ID
'categories' => ['Electronics', 'Filters']
],
[
'product_id' => 456,
'categories' => ['Lenses', 'Infrared Filters']
]
];
foreach ($products as $product) {
// Assign categories to the product
wp_set_object_terms($product['product_id'], $product['categories'], 'product_cat');
}
}
add_action('init', 'assign_products_to_categories');
3. Sort Categories Alphabetically
WooCommerce already sorts categories alphabetically by default. If you’d like to ensure this behavior programmatically or modify it, use this code snippet:
function sort_product_categories_alphabetically($query) {
if (is_tax('product_cat')) {
$query->set('orderby', 'name'); // Sort by category name
$query->set('order', 'ASC'); // Sort in ascending order
}
}
add_action('pre_get_posts', 'sort_product_categories_alphabetically');
4. Sort Products Within Categories
You can sort products within a category programmatically using menu_order, title, price, or custom meta fields. Add this to your functions.php:
function sort_products_within_category($query) {
if (!is_admin() && $query->is_main_query() && is_tax('product_cat')) {
$query->set('orderby', 'title'); // Sort by product title
$query->set('order', 'ASC'); // Sort in ascending order
}
}
add_action('pre_get_posts', 'sort_products_within_category');
Replace 'title' with other options like:
'menu_order'(WooCommerce’s default order).'meta_value'(custom field, e.g., price or SKU).'date'(order by creation date).
5. Sort Categories Hierarchically
If you’re dealing with parent and child categories, you can display them in a hierarchical structure using this snippet:
function display_hierarchical_categories() {
$categories = get_terms([
'taxonomy' => 'product_cat',
'orderby' => 'name',
'order' => 'ASC',
'hide_empty' => false
]);
echo '<ul>';
foreach ($categories as $category) {
if ($category->parent == 0) { // Parent category
echo '<li>' . esc_html($category->name);
// Get child categories
$child_categories = get_terms([
'taxonomy' => 'product_cat',
'orderby' => 'name',
'order' => 'ASC',
'parent' => $category->term_id,
'hide_empty' => false
]);
if (!empty($child_categories)) {
echo '<ul>';
foreach ($child_categories as $child) {
echo '<li>' . esc_html($child->name) . '</li>';
}
echo '</ul>';
}
echo '</li>';
}
}
echo '</ul>';
}
add_shortcode('hierarchical_product_categories', 'display_hierarchical_categories');
Use the [hierarchical_product_categories] shortcode to display this hierarchy.
6. Bulk Assign Products to Categories
If you have a CSV or a list of products that need to be categorized, you can dynamically handle this with a script.
Example: Assign Products Based on a Custom Field
If your products have a custom field (e.g., category_assignment) that contains the category name:
function bulk_assign_categories() {
$products = wc_get_products(['limit' => -1]); // Get all products
foreach ($products as $product) {
$category = get_post_meta($product->get_id(), 'category_assignment', true);
if ($category) {
wp_set_object_terms($product->get_id(), $category, 'product_cat', true);
}
}
}
add_action('init', 'bulk_assign_categories');
7. Visualize Categories on Frontend
If you want to display all categories or a sorted list, use the wp_list_categories function:
function display_sorted_product_categories() {
wp_list_categories([
'taxonomy' => 'product_cat',
'orderby' => 'name',
'order' => 'ASC',
'title_li' => ''
]);
}
add_shortcode('sorted_product_categories', 'display_sorted_product_categories');
Use the [sorted_product_categories] shortcode to render the sorted categories.
8. Automate Category Creation and Sorting in WooCommerce Importer
If you’re using the WooCommerce CSV importer, you can ensure categories are auto-created and assigned as explained in the earlier setup. The following steps summarize the process:
- CSV Column Mapping: Map
Web item categoryorItem categorytoproduct_catin the importer. - Auto-Create Categories: Ensure
wp_set_object_termsautomatically creates categories during import. - Sort Categories: Use the
orderbyparameter to enforce sorting when displaying categories.
This setup enables you to dynamically create, assign, and sort categories both programmatically and via the WooCommerce importer, making category management efficient and automated.
Bonus More Depth
To sort products dynamically based on values in custom fields like [display_wavelength_range_high] or [display_wavelength_range_low], you can use WordPress meta queries. Here’s how to set this up:
1. Add a Query to Sort by Custom Fields
Use the pre_get_posts action to modify the WooCommerce product query and sort products by custom fields.
Example Code for Sorting by Wavelength Range:
function sort_products_by_wavelength($query) {
if (!is_admin() && $query->is_main_query() && is_shop()) {
$query->set('meta_key', '_wavelength_range_high'); // Replace with the meta key to sort by
$query->set('orderby', 'meta_value_num'); // Sort by numeric values
$query->set('order', 'ASC'); // Ascending order (use 'DESC' for descending)
}
}
add_action('pre_get_posts', 'sort_products_by_wavelength');
2. Sorting by Both High and Low Values
If you want to sort first by _wavelength_range_low and then _wavelength_range_high as a secondary criterion, you can use a meta query.
Example Code:
function sort_products_by_wavelength_range($query) {
if (!is_admin() && $query->is_main_query() && (is_shop() || is_product_category())) {
$query->set('meta_query', [
'relation' => 'AND',
[
'key' => '_wavelength_range_low',
'type' => 'NUMERIC',
'compare' => 'EXISTS'
],
[
'key' => '_wavelength_range_high',
'type' => 'NUMERIC',
'compare' => 'EXISTS'
]
]);
$query->set('orderby', [
'meta_value_num' => '_wavelength_range_low', // Primary sort
'meta_value_num_secondary' => '_wavelength_range_high' // Secondary sort
]);
$query->set('order', 'ASC'); // Ascending order for both
}
}
add_action('pre_get_posts', 'sort_products_by_wavelength_range');
3. Sorting Results on a Custom Page or Shortcode
If you’re not working with WooCommerce’s shop or category pages, you can query and display products sorted by these fields using WP_Query.
Example for a Custom Query:
function display_sorted_products_by_wavelength() {
$args = [
'post_type' => 'product',
'posts_per_page' => -1,
'meta_query' => [
'relation' => 'AND',
[
'key' => '_wavelength_range_low',
'type' => 'NUMERIC',
'compare' => 'EXISTS'
],
[
'key' => '_wavelength_range_high',
'type' => 'NUMERIC',
'compare' => 'EXISTS'
]
],
'orderby' => [
'meta_value_num' => '_wavelength_range_low',
'meta_value_num_secondary' => '_wavelength_range_high'
],
'order' => 'ASC'
];
$query = new WP_Query($args);
if ($query->have_posts()) {
echo '<ul class="sorted-products">';
while ($query->have_posts()) {
$query->the_post();
// Fetch custom fields
$wavelength_low = get_post_meta(get_the_ID(), '_wavelength_range_low', true);
$wavelength_high = get_post_meta(get_the_ID(), '_wavelength_range_high', true);
echo '<li>';
echo '<a href="' . get_the_permalink() . '">' . get_the_title() . '</a>';
echo ' - Wavelength Range: ' . esc_html($wavelength_low) . ' - ' . esc_html($wavelength_high);
echo '</li>';
}
echo '</ul>';
wp_reset_postdata();
} else {
echo '<p>No products found.</p>';
}
}
add_shortcode('sorted_products_by_wavelength', 'display_sorted_products_by_wavelength');
- Use the
[sorted_products_by_wavelength]shortcode to display products sorted by the custom fields on any page.
4. Frontend Dropdown to Sort by High or Low Wavelength
If you want users to dynamically sort products on the frontend, add a dropdown for sorting.
Add Dropdown to Shop Page:
add_action('woocommerce_before_shop_loop', 'add_wavelength_sorting_dropdown');
function add_wavelength_sorting_dropdown() {
if (is_shop() || is_product_category()) {
?>
<form method="get" id="wavelength-sorting-form">
<select name="sort_wavelength" onchange="this.form.submit()">
<option value="">Sort by Wavelength</option>
<option value="low_to_high" <?php selected('low_to_high', $_GET['sort_wavelength'] ?? ''); ?>>Low to High</option>
<option value="high_to_low" <?php selected('high_to_low', $_GET['sort_wavelength'] ?? ''); ?>>High to Low</option>
</select>
</form>
<?php
}
}
Modify Query Based on Dropdown Selection:
add_action('pre_get_posts', 'sort_products_by_dropdown');
function sort_products_by_dropdown($query) {
if (!is_admin() && $query->is_main_query() && is_shop() && isset($_GET['sort_wavelength'])) {
if ($_GET['sort_wavelength'] === 'low_to_high') {
$query->set('meta_key', '_wavelength_range_low');
$query->set('orderby', 'meta_value_num');
$query->set('order', 'ASC');
} elseif ($_GET['sort_wavelength'] === 'high_to_low') {
$query->set('meta_key', '_wavelength_range_high');
$query->set('orderby', 'meta_value_num');
$query->set('order', 'DESC');
}
}
}
5. Verify the Custom Fields
Ensure the custom fields _wavelength_range_low and _wavelength_range_high exist and contain numeric values for all products you want to sort. Use the following SQL query to verify in the database:
SELECT post_id, meta_key, meta_value
FROM wp_postmeta
WHERE meta_key IN ('_wavelength_range_low', '_wavelength_range_high')
ORDER BY meta_value + 0 ASC;
6. Styling (Optional)
Add custom CSS for better presentation:
.sorted-products {
list-style: none;
margin: 0;
padding: 0;
}
.sorted-products li {
margin: 10px 0;
font-size: 16px;
}
Results
- Products are now sorted by
_wavelength_range_highand_wavelength_range_lowvalues on shop/category pages or custom query pages. - A dropdown lets users dynamically sort by wavelength values.
- A shortcode displays sorted products anywhere on the site.
Bonus Dynamic Sort
Yes, you can dynamically create categories based on the sorted values (e.g., _wavelength_range_low and _wavelength_range_high) and then assign products to these categories. This involves programmatically grouping products into ranges and associating them with newly created categories. Here’s how to do it:
1. Define Wavelength Ranges and Categories
Start by defining the wavelength ranges you want to use for creating categories. For example:
- Wavelength Range:
0-200nm→ Category: “Low Wavelength” - Wavelength Range:
201-500nm→ Category: “Medium Wavelength” - Wavelength Range:
501-1000nm→ Category: “High Wavelength”
2. Create Categories Based on Wavelength Ranges
You can dynamically create WooCommerce categories for the ranges if they don’t already exist:
function create_wavelength_categories() {
// Define wavelength ranges and corresponding category names
$wavelength_ranges = [
'Low Wavelength' => ['min' => 0, 'max' => 200],
'Medium Wavelength' => ['min' => 201, 'max' => 500],
'High Wavelength' => ['min' => 501, 'max' => 1000]
];
foreach ($wavelength_ranges as $category_name => $range) {
// Check if the category exists, and create it if it doesn't
if (!term_exists($category_name, 'product_cat')) {
wp_insert_term(
$category_name, // Category name
'product_cat', // Taxonomy
[
'description' => "Products with wavelengths between {$range['min']}nm and {$range['max']}nm",
'slug' => sanitize_title($category_name)
]
);
}
}
}
add_action('init', 'create_wavelength_categories');
3. Assign Products to Categories Based on Wavelength
Loop through all products, check their _wavelength_range_low and _wavelength_range_high custom fields, and assign them to the appropriate category based on their wavelength.
function assign_products_to_wavelength_categories() {
// Define wavelength ranges and corresponding category names
$wavelength_ranges = [
'Low Wavelength' => ['min' => 0, 'max' => 200],
'Medium Wavelength' => ['min' => 201, 'max' => 500],
'High Wavelength' => ['min' => 501, 'max' => 1000]
];
// Get all products
$products = wc_get_products(['limit' => -1]); // Get all products
foreach ($products as $product) {
$low_wavelength = get_post_meta($product->get_id(), '_wavelength_range_low', true);
$high_wavelength = get_post_meta($product->get_id(), '_wavelength_range_high', true);
if (!empty($low_wavelength) && !empty($high_wavelength)) {
foreach ($wavelength_ranges as $category_name => $range) {
// Check if the product fits within the range
if ($low_wavelength >= $range['min'] && $high_wavelength <= $range['max']) {
// Assign the category to the product
wp_set_object_terms($product->get_id(), $category_name, 'product_cat', true);
}
}
}
}
}
add_action('init', 'assign_products_to_wavelength_categories');
4. Display Sorted Categories
You can display the created categories on the frontend using a shortcode or WooCommerce widget. Here’s a shortcode to display all wavelength categories:
function display_wavelength_categories() {
// Get all categories
$categories = get_terms([
'taxonomy' => 'product_cat',
'orderby' => 'name',
'order' => 'ASC',
'hide_empty' => false
]);
$output = '<ul class="wavelength-categories">';
foreach ($categories as $category) {
if (strpos($category->name, 'Wavelength') !== false) { // Only show wavelength categories
$output .= '<li>';
$output .= '<a href="' . esc_url(get_term_link($category)) . '">' . esc_html($category->name) . '</a>';
$output .= '</li>';
}
}
$output .= '</ul>';
return $output;
}
add_shortcode('wavelength_categories', 'display_wavelength_categories');
Use the [wavelength_categories] shortcode on any page to list your wavelength categories.
5. Automatically Update Categories on Product Save
To ensure categories are always updated when product wavelengths change, you can hook into the product save action:
function update_product_wavelength_category($post_id) {
if (get_post_type($post_id) !== 'product') {
return;
}
// Define wavelength ranges and corresponding category names
$wavelength_ranges = [
'Low Wavelength' => ['min' => 0, 'max' => 200],
'Medium Wavelength' => ['min' => 201, 'max' => 500],
'High Wavelength' => ['min' => 501, 'max' => 1000]
];
$low_wavelength = get_post_meta($post_id, '_wavelength_range_low', true);
$high_wavelength = get_post_meta($post_id, '_wavelength_range_high', true);
if (!empty($low_wavelength) && !empty($high_wavelength)) {
foreach ($wavelength_ranges as $category_name => $range) {
// Check if the product fits within the range
if ($low_wavelength >= $range['min'] && $high_wavelength <= $range['max']) {
// Assign the category to the product
wp_set_object_terms($post_id, $category_name, 'product_cat', true);
}
}
}
}
add_action('save_post', 'update_product_wavelength_category');
6. Frontend Sorting by Category
To let users sort products by wavelength categories on the frontend, simply use the default WooCommerce category filtering:
- Add a WooCommerce Product Categories widget to your sidebar or menu.
- Users can filter products by categories, which are already grouped by wavelength.
Alternatively, add a dropdown to sort categories dynamically:
add_action('woocommerce_before_shop_loop', 'add_category_sorting_dropdown');
function add_category_sorting_dropdown() {
if (is_shop() || is_product_category()) {
?>
<form method="get" id="category-sorting-form">
<select name="product_cat" onchange="this.form.submit()">
<option value="">Sort by Wavelength Category</option>
<option value="low-wavelength">Low Wavelength</option>
<option value="medium-wavelength">Medium Wavelength</option>
<option value="high-wavelength">High Wavelength</option>
</select>
</form>
<?php
}
}
Final Workflow:
- Define Wavelength Ranges: Use
create_wavelength_categoriesto programmatically create categories. - Assign Products: Use
assign_products_to_wavelength_categoriesto categorize products dynamically based on their wavelength ranges. - Frontend:
- Use
[wavelength_categories]to display categories. - Use WooCommerce widgets or dropdowns to allow users to filter products by wavelength categories.
- Use
This way, products are sorted into dynamically created wavelength-based categories and are easily viewable and filterable by users! 🚀