Question

I am trying to add a class to a checkout page if the checkout contains a subscription renewal. Woocommerce provides wcs_cart_contains_renewal() to check. I am using this code but obviously missing something as it's not working.

$cart_items = wcs_cart_contains_renewal();
    if ( ! empty( $cart_items ) ) {

    add_filter( 'body_class','my_body_classes' );
    function my_body_classes( $classes ) {
        $classes[] = 'renewal-order';
        return $classes;
    }
}

Any help on how to make this work?

Was it helpful?

Solution

As @cjbj noted in a comment, this is probably a timing issue. This means that instead of directly adding the code to functions.php you need to wrap it inside a callback function and attach it to a later firing action. WordPress, themes and plugins too, loads and does things in certain order. Thus some code needs to be added with actions to make them properly.

Personally, I usually add body_class filtering, if it depends on some data, on template_redirect (Fires before determining which template to load) action to make sure the code will have all the data it needs to determine how to filter the classes.

// Hook anonymous callback to template_redirect action
add_action(
    'template_redirect',
    function(){
        // Get data
        $cart_items = wcs_cart_contains_renewal();
        // Check for truthy condition
        if ( $cart_items ) {
            // Hook anonymous callback to body_class filter
            add_filter(
                'body_class',
                function( $classes ) {
                    // Add additional class
                    $classes[] = 'renewal-order';
                    return $classes;
                }
            );
        }
    }
);

You can use named callback instead of anonymous ones, if you wish.

OTHER TIPS

The body_class filter is called inside the function with the same name, which is supposed to be in your theme like this: <body <?php body_class(); ?>>

Now, you don't make clear where your piece of code is called, but if it is not attached to wp_head or another hook inside the <head> tag of you page, you are adding a filter to a function that has already been called. As a result nothing happens.

While I am running with Antti's code I did manage to get it working. I think the issue with my initial code was it needed to be wrapped up within the function.

function inline_css() {
    $cart_items = wcs_cart_contains_renewal();
    if ( ! empty( $cart_items ) ) {
    add_filter( 'body_class','my_body_classes' );
        function my_body_classes( $classes ) {
            $classes[] = 'renewal-order';
        return $classes;
        }
    }

}
add_action( 'wp_head', 'inline_css', 0 );
Licensed under: CC-BY-SA with attribution
Not affiliated with wordpress.stackexchange
scroll top