How to Override WooCommerce Template Files

WooCommerce has been designed in such a way that most aspects of the popular eCommerce plugin can safely modified in WordPress. But unless you’re a strong PHP programmer, at first glance it can be a little confusing.

In this post, we’re going to take a look at the two methods used to override WooCommerce template files – editing files in your child theme, and using hooks. To help illustrate what’s involved, let’s take a hypothetical example:

How To Change a WooCommerce Product Titles from H2 to H3

If you view the source of your WooCommerce Shop page, the product names might look something like this:

<h2 class="woocommerce-loop-product__title">Product Name</h2>

In our hypothetical example, let’s say we want to change the H2 tags to H3. Where do we begin?

Method 1 – File Override

The WooCommerce plugin itself has a folder called templates, which contains all the default template files need for WooCommerce to work with any theme. However, your theme might already be overriding some of these template files. Look for a folder called woocommerce in your theme folder. If present, you will notice that your theme doesn’t override every template file, only those files necessary to integrate WooCommerce with that specific theme.

The file we need in this instance is called content-product.php. As we work through this example, you will become more familiar with these template files, but the naming convention used is helpful when finding the file we want to edit. Then, when you open the file, the comments at the top should confirm that we’re looking in the right place. In this case:

<?php
/**
 * The template for displaying product content within loops
 *
 * This template can be overridden by copying it to 
   yourtheme/woocommerce/content-product.php. 

To safely make changes to this file, we need to copy it into your Child theme. If the file is present in your Parent theme, use that; otherwise, copy it from the WooCommerce plugin.

As soon as the file is placed in your Child theme, it becomes the used by WordPress, overriding the same file in your Parent theme (if present) and the original file in the WooCommerce plugin.

Now, open that file and find the following code:

/** 
 * Hook: woocommerce_shop_loop_item_title. 
 *
 * @hooked woocommerce_template_loop_product_title - 10 
 */
do_action( 'woocommerce_shop_loop_item_title' );

The do_action function execute any functions hooked on the action hook woocommerce_shop_loop_item_title, which we can see from the comments is the function woocommerce_template_loop_product_title with priority 10.

This function is defined in the WooCommerce plugin file:

includes/wc-template-functions.php

Open that file and search for the woocommerce_template_loop_product_title function and you will find it defined as:

if ( ! function_exists( 'woocommerce_template_loop_product_title' ) ) {

    /**
      * Show the product title in the product loop.
      * By default this is an H2.
      */
    function woocommerce_template_loop_product_title() {
        echo '<h2 class="' . esc_attr( apply_filters( 'woocommerce_product_loop_title_classes', 'woocommerce-loop-product__title' ) ) . '">' . get_the_title() . '</h2>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    }
 }

This is the code that need overriding. The simplest way to do this is to edit the content-product.php file in your Child theme. You would comment out the do_action function so that it doesn’t fire, and then copy in the echo function, changing the H2 to H3:

/** 
 * Hook: woocommerce_shop_loop_item_title. 
 *
 * @hooked woocommerce_template_loop_product_title - 10 
 */
// do_action( 'woocommerce_shop_loop_item_title' );

echo '<h3 class="' . esc_attr( apply_filters( 'woocommerce_product_loop_title_classes', 'woocommerce-loop-product__title' ) ) . '">' . get_the_title() . '</h3>';

Now, as the page loads, the default action no longer runs, and your new code will fire instead. The product titles are now enclosed in H3 tags instead of H2 tags.

Method 2 – Using Hooks

Once you’ve seen how the file override is done, it’s not that scary. It does allow for quick and simple modifications to the WooCommerce template files. However, this method is not ideal for a couple of reasons:

First, from time to time, WooCommerce does change it’s template files, so you may find this file is out of date after some update in the future. Also, by commenting out the do_action function, you can no longer add functionality to that hook – you’re essentially removing the hook from the WordPress code. Are you absolutely sure that your theme and all your plugins don’t make use of this hook?

The better way to making this change, and the way everything should be done is WordPress, is to make use of the hooks provided. We already know the product titles are printed out via the woocommerce_shop_loop_item_title hook. So how to override that default functionality?

Previously, we determined that the function woocommerce_template_loop_product_title runs at the woocommerce_shop_loop_item_title hook with priority 10. What we need to do is “unhook” that function, and replace it with our own function.

You can do this by adding the following code to your functions.php file:

remove_action( 'woocommerce_shop_loop_item_title','woocommerce_template_loop_product_title', 10 );
add_action('woocommerce_shop_loop_item_title', 'your_custom_function_call', 10 );
function your_custom_function_call() {
     echo '<h3 class="' . esc_attr( apply_filters( 'woocommerce_product_loop_title_classes', 'woocommerce-loop-product__title' ) ) . '">' . get_the_title() . '</h3>';
}

We use remove_action to remove the default woocommerce_template_loop_product_title function, then replace it with by using add_action to insert our own custom function your_custom_function_call. Finally, we just need to define our custom function, by copying the code original function definition and making the appropriate changes to it.

Leave a Comment