Specific ordering of WooCommerce attribute items

Hi all,

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

image

For backend ordering i use the great Plugin : Simple Custom Post Order – WordPress plugin | WordPress.org

Make sure you select the taxonomies:
image

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;
}