Search code examples
phpwordpresswoocommercecarttaxonomy-terms

Add a body class for a specific product category on WooCommerce cart items


I want to have a different layout after somebody added a product of the category "Variation" to the cart.

I have a code that works fine, but destroys the layout. It looks if a product of a certain category is in the cart, if so, it adds a class to the body_class

/* ADD PRODUCT CLASS TO BODYCLASS  */
add_filter( 'body_class', 'prod_class_to_body_class' );

function prod_class_to_body_class() {

    // set flag
    $cat_check = false;

    // check cart items 
    foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {

        $product = $cart_item['data'];

        if ( has_term( 'my_product_cat', 'product_cat', $product->id ) ) {
            $cat_check = true;
            break;
        }
    }

    // if a product in the cart has the category "my_product_cat", add "my_class" to body_class
    if ( $cat_check ) {
          $classes[] = 'my_class';
    }

    return $classes;
}

If I look into the source code, I can see the new class, if I have a product of the category 'my_product_cat' in the cart. But the layout is a disaster.

Does anybody see a mistake?


Solution

  • There is multiple mistakes:

    • Main function variable argument is missing
    • For has_term() usage in cart, always use $cart_item['product_id'] to make it work with product variation items.

    Also your code can be simplified. Try the following:

    // ADD PRODUCT CLASS TO BODYCLASS
    add_filter( 'body_class', 'prod_class_to_body_class' );
    function prod_class_to_body_class( $classes ) {
        $check_cat = 'my_product_cat'; // Product category term to check
        $new_class = 'my_class'; // Class to be added
    
        // Loop through cart items 
        foreach ( WC()->cart->get_cart() as $cart_item ) {
            // Check for a product category term
            if ( has_term( $check_cat, 'product_cat', $cart_item['product_id'] ) ) {
                $classes[] = $new_class; // Add the new class
                break; // Stop the loop
            }
        }
        return $classes;
    }
    

    Code goes in functions.php file of your active child theme (or active theme). Tested and works.