When embarking on a new WooCommerce project, there are many ways to tackle template modification. I’ll go through the most common methods below, and explain the method I use and why I think it’s the best way!
Override a Template File in your Theme
We’ve all done it; create a “woocommerce” folder in your theme folder and copy the relevant template files over.
While this method works well, I still don’t recommend it. WooCommerce regularly update these templates, and your modified version will soon become out of date.
Modify a Template File Directly
Just no. You should never do this! Next time you update WooCommerce, your changes are gone.
Using Actions and Filters
Yes! Now we’re talking.
This is by far the best method of customising your WooCommerce templates. WooCommerce very kindly include a whole load of actions and filters that you can latch onto in order to modify any aspect of the default template files.
At first, it may seem daunting. But fear not! The following guide should get you well on your way.
Finding the Available Actions
There are a lot of them, that’s for sure. The method I use to find out which actions I can use is to literally browse the template files on github. This allows me to use the search to find snippets of text within the files.
The template files display a lot of useful information. Let’s consider the templates/single-product.php template to start with.
* woocommerce_before_main_content hook.
* @hooked woocommerce_output_content_wrapper - 10 (outputs opening divs for the content)
* @hooked woocommerce_breadcrumb - 20
The first action we can see in the file is called via do_action( 'woocommerce_before_main_content' );. Anytime you see this do_action function, it’s likely some actions are hooked in at that point.
WooCommerce (and WordPress in general) will often use these actions to add template parts. In the template file you can see that the hooked functions have been clearly labelled for you, along with their priorities.
There are 2 hooked functions on woocommerce_before_main_content, woocommerce_output_content_wrapper and woocommerce_breadcrumb. The priorities (10, 20) simply let you know what order the hooked functions will appear in; 10 being first, 20 being last. 30 would appear after 20, etc.
So this is a great way of finding out what actions are available. Anywhere an action is available, you can output the contents of a custom function. For example, you may want to add a content wrapper (opening and closing div tags) before and after the main content action. You’d use the woocommerce_before_main_content and woocommerce_after_main_content actions. You can also easily remove or move any of the actions that are there, for example, you could remove the breadcrumbs with 1 line of code (see below).
Using One of The Actions
Let’s take our earlier example of adding opening and closing div tags around the main content. You can use this method to modify the layout of the page to match that of your own frontend code.
So here I have added both the opening and closing div tag. You’d add this to your functions.php (or equivalent) file in your theme.
First of all, we tell our iconic_open_div function to execute on the woocommerce_before_main_content action with a priority of 5. This will output our opening div tag just before the WooCommerce content wrapper.
Then we closed it on the woocommerce_after_main_content action, with a priority of 50 to make sure it comes last.
That’s it! WooCommerce can modify that template all they want, as long as those actions remain in place, our changes will never be lost, and will never cause issues when new functionality is added.
Another example could be that you want to output some text just after your product title in the catalog pages. We’d need to modify the templates/content-product.php template.
Open the file and you will see that woocommerce_template_loop_product_title is hooked to the woocommerce_shop_loop_item_title action. We can hook in just after it, as we can see it has a priority of 10.
As you can see, when using the available hooks to modify your templates, the options are endless. On top of that, it is far safer in terms of future updates, and also for your sanity when coming back to the code at a later date.
Let me know if you use this method on one of your next builds!