Hi all,
My client wanted to have a specific order of attributes used for WooCommerce variations to appear in the frontend (like sizes).

For backend ordering i use the great Plugin : Simple Custom Post Order – WordPress plugin | WordPress.org
Make sure you select the taxonomies:

And then re-order the items in the attributes table → configure terms:
Here is the code snippet to respect this order in the frontend; make sure to set your attribute slug on line 17:
$custom_order_attributes = array( ‘pa_maten’, ‘pa_kleur’ );
<?php
/**
* Respect Simple Custom Post Order plugin ordering for WooCommerce attributes
* Add this to your child theme's functions.php or a custom plugin
*/
if ( ! is_admin() ) {
add_filter( 'woocommerce_dropdown_variation_attribute_options_args', 'custom_order_variation_attribute_dropdown', 10, 1 );
add_filter( 'woocommerce_product_get_attributes', 'custom_order_product_attributes', 10, 2 );
add_filter( 'get_terms_defaults', 'custom_default_term_order_for_attributes', 10, 2 );
}
/**
* Order variation dropdown options according to Simple Custom Post Order
*/
function custom_order_variation_attribute_dropdown( $args ) {
// Define attributes to apply custom ordering
$custom_order_attributes = array( 'pa_maten', 'pa_kleur' );
// Only apply to specified attributes
if ( isset( $args['attribute'] ) && in_array( $args['attribute'], $custom_order_attributes ) ) {
if ( ! empty( $args['options'] ) ) {
$ordered_options = array();
// Get terms with their custom order
$terms = get_terms( array(
'taxonomy' => $args['attribute'],
'hide_empty' => false,
'orderby' => 'term_order', // This is set by Simple Custom Post Order
'order' => 'ASC'
) );
// Create ordered array based on term slugs
foreach ( $terms as $term ) {
if ( in_array( $term->slug, $args['options'] ) ) {
$ordered_options[] = $term->slug;
}
}
// Replace options with ordered options
if ( ! empty( $ordered_options ) ) {
$args['options'] = $ordered_options;
}
}
}
return $args;
}
/**
* Order attribute terms in variation swatches and other displays
*/
function custom_order_product_attributes( $attributes, $product ) {
// Define attributes to apply custom ordering
$custom_order_attributes = array( 'pa_maten', 'pa_kleur' );
if ( ! empty( $attributes ) ) {
foreach ( $attributes as $attribute_name => $attribute ) {
// Check if it's one of our specified attributes
if ( $attribute->is_taxonomy() && in_array( $attribute->get_name(), $custom_order_attributes ) ) {
$taxonomy = $attribute->get_taxonomy();
$terms = wc_get_product_terms( $product->get_id(), $taxonomy, array(
'orderby' => 'term_order',
'order' => 'ASC'
) );
if ( ! empty( $terms ) ) {
$attribute->set_options( wp_list_pluck( $terms, 'term_id' ) );
}
}
}
}
return $attributes;
}
/**
* Additional filter for variation form display
*/
add_filter( 'woocommerce_variation_option_name', 'custom_order_variation_option_name', 10, 1 );
function custom_order_variation_option_name( $value ) {
return $value;
}
/**
* Ensure term_order is used globally for pa_maten and pa_kleur
*/
function custom_default_term_order_for_attributes( $defaults, $taxonomies ) {
// Define attributes to apply custom ordering
$custom_order_attributes = array( 'pa_maten', 'pa_kleur' );
// Check if taxonomies is an array
if ( is_array( $taxonomies ) ) {
foreach ( $custom_order_attributes as $attribute ) {
if ( in_array( $attribute, $taxonomies ) ) {
$defaults['orderby'] = 'term_order';
$defaults['order'] = 'ASC';
break;
}
}
}
// Check if taxonomies is a string
elseif ( in_array( $taxonomies, $custom_order_attributes ) ) {
$defaults['orderby'] = 'term_order';
$defaults['order'] = 'ASC';
}
return $defaults;
}
