By default, WooCommerce allows sorting products by date, price, popularity, and more, but it does not provide an easy way to display products in a custom order within a category. If you’re looking to showcase specific products first while displaying the rest of the category items below, this guide is for you!
We’ll create a shortcode that:
- Displays selected products in a custom order.
- Lists all remaining products from a specified category below them.
- Ensures correct column spacing for a neat and responsive layout.
Let’s dive in!
Step 1: Add the Custom Shortcode in Your Theme’s functions.php File
Copy and paste the following PHP code into your functions.php
file:
function custom_product_order_shortcode($atts) {
$atts = shortcode_atts([
'ids' => '', // Custom product IDs (comma-separated)
'category' => '', // Product category slug
'columns' => '3' // Default to 3 columns
], $atts, 'custom_order_products');
$custom_ids = !empty($atts['ids']) ? array_map('intval', explode(',', $atts['ids'])) : [];
$columns = intval($atts['columns']); // Convert columns to integer
// Set WooCommerce columns dynamically
add_filter('loop_shop_columns', function () use ($columns) {
return $columns;
});
// Base query args
$args = [
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => -1,
'orderby' => 'post__in', // Maintain custom order
'post__in' => $custom_ids,
'tax_query' => []
];
// Add category filter if provided
if (!empty($atts['category'])) {
$args['tax_query'][] = [
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $atts['category']
];
}
// Get remaining products from the category (if custom IDs are provided)
if (!empty($custom_ids)) {
$remaining_products = get_posts([
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => -1,
'fields' => 'ids',
'exclude' => $custom_ids,
'tax_query' => [
[
'taxonomy' => 'product_cat',
'field' => 'slug',
'terms' => $atts['category'],
],
],
]);
// Merge selected and remaining products while keeping the custom order
$args['post__in'] = array_merge($custom_ids, $remaining_products);
}
// Start WooCommerce output buffering
ob_start();
// Force WooCommerce grid classes
echo '<div class="woocommerce"><ul class="products columns-' . esc_attr($columns) . ' products-' . esc_attr($columns) . '">';
// Custom WooCommerce Query
$query = new WP_Query($args);
if ($query->have_posts()) {
while ($query->have_posts()) {
$query->the_post();
wc_get_template_part('content', 'product'); // WooCommerce default product template
}
wp_reset_postdata();
} else {
echo '<p>No products found.</p>';
}
echo '</ul></div>'; // Close wrapper
return ob_get_clean();
}
add_shortcode('custom_product_order', 'custom_product_order_shortcode');
Step 2: Adjust the CSS for Proper Product Columns
Ensure that the products are displayed correctly in a three-column layout. Add the following CSS to your theme’s stylesheet (style.css
):
ul.products .product {
padding: calc((var(--woocommerce_archive_grid_column_spacing)) / 2);
}
.products-3 > li {
width: 33.3333%;
}
.product {
position: relative;
}
Step 3: Modify WooCommerce’s Default Column Setting (Optional)
If you’re building a theme, you might want to force WooCommerce to display three products per row. Add the following snippet to functions.php
:
add_filter('loop_shop_columns', 'loop_columns', 999);
if (!function_exists('loop_columns')) {
function loop_columns() {
return 3; // 3 products per row
}
}
Step 4: Use the Shortcode in Your Page or Post
You can now use the following shortcode to display products in a custom order followed by the rest of the category:
[custom_product_order ids="1067, 1058, 1121, 1400, 1136" category="category name" columns="3"]
How It Works:
- The first five products (IDs: 1067, 1058, 1121, 1400, 1136) will appear first.
- The remaining products from the “planter-boxes” category will be displayed after them.
- The products will be arranged in 3 columns
Conclusion
With this simple function, you now have full control over the product display order while maintaining a clean, organized layout. This approach is especially useful for featured products, landing pages, or promotional sections in your WooCommerce store.
Have any questions? Feel free to ask in the comments below!