Image may be NSFW.
Clik here to view.
While it’s not technically possible to override a WordPress widget (and remember WooCommerce widgets are nothing more than WordPress widgets), WooCommerce is just so extendable and pluggable and flexible, that some widget functionality can be nearly completely overridden just using the standard WooCommerce template files and/or template functions. For the widgets that aren’t as pluggable, or if you need greater control, you have the option to un-register a core WooCommerce widget and subclass it, or even duplicate it and change it wholesale, all without modifying a single core file, thus maintaining a clean upgrade path.
Your widget override options, listed in order of preference, starting with the most preferred, down to the least preferred but most powerful, are as follows:
- Use the
widget_display_callback
filter to alter configuration details - Hook into any provided filters/actions
- Override a WooCommerce template file
- Override a pluggable WooCommerce template function
- Subclass, modify and register a widget
- Duplicate, modify and register a widget
The rest of this article will be devoted to describing, with code examples where applicable, these six options. Note also that while this is written with WooCommerce in mind, most of the strategies described are completely applicable to any WordPress widgets.
Option 1 – Hook into widget_display_callback
filter
You can hook onto the widget_display_callback
filter to change the configuration settings of a widget on-the-fly. Not really sure how useful this is, and I’m not covering it in great detail as this article is geared towards more substantial behavior overrides. Still, a quick example of how you might use it, here changing the Cart widget title:
add_filter( 'widget_display_callback', 'rename_widget', 10, 3 ); function rename_widget( $settings, $widget, $args ) { if ( get_class( $widget ) == 'Custom_WooCommerce_Widget_Cart' ) { $settings['title'] = 'My Cart'; } return $settings; }
Option 2 – Hook into widget filters/actions
I didn’t include this method initially as I don’t know how many widgets actually provide their own action/filter hooks for modifying functionality, but there’s certainly no reason that they couldn’t, and if they should, this would be an ideal way to change the widget behavior. I won’t cover the basics of using WordPress actions/filters, for that check out the WordPress Plugin API codex page.
Option 3 – Override a WooCommerce widget template file
This is the next most preferred means of changing a WooCommerce widget’s behavior, but it’s not always possible. To determine whether you can use this method, you’ll have to inspect the widget class in question. Lets use the WooCommerce Cart widget as an example, which produces a mini cart like the following when active:
Image may be NSFW.
Clik here to view.
The code for this widget can be found at woocommerce/widgets/widget-cart.php
. If we take a look at that file, we’ll find that it doesn’t contain much beyond the boilerplate widget code, though it does contain the following line:
$woocommerce->mfunc_wrapper( 'woocommerce_mini_cart()', 'woocommerce_mini_cart', array( 'list_class' => $hide_if_empty ? 'hide_cart_widget_if_empty' : '' ) );
Without diving into the specifics of what’s going on here, suffice it to say that this results in a call to the woocommerce_mini_cart()
function, which will do most of the work of creating this widget on the frontend. When we look at the woocommerce_mini_cart()
, found in woocommerce/woocommerce-template.php
, we see that it in turn does very little other than loading cart/mini-cart.php
:
woocommerce_get_template( 'cart/mini-cart.php', $args );
Which you can find at woocommerce/cart/mini-cart.php
and actually contains the code that renders that mini cart widget.
Now this may seem like a lot of effort or unnecessary code just to display a mini cart, but what this design provides is quite a lot of flexibility, with multiple avenues for modifying the widget behavior. Thanks to all that flexibility we can completely change the look and feel of this widget by simply overriding the mini-cart.php template file. This is something I’ve covered fully in another article, but the overview is to create a directory named woocommerce
within your theme, copy over the template file in question, and modify things to our hearts content. In this example we’d copy woocommerce/templates/cart/mini-cart.php
to yourtheme/woocommerce/cart/mini-cart.php
and change whatever we want in that file. The template file in the theme will be used in place of the core WooCommerce template.
Option 4 – Override a plugable widget template function
This method is quite related to the template file method described in the previous section. If you’ve read through and paid attention to Option 3, you’ll remember the function woocommerce_mini_cart()
, found in woocommerce/woocommerce-template.php
which loaded the mini-cart.php
template file. This function is known as a pluggable function because it can be replaced with your own custom version. The full function looks like the following:
if ( ! function_exists( 'woocommerce_mini_cart' ) ) { function woocommerce_mini_cart( $args = array() ) { $defaults = array( 'list_class' => '' ); $args = wp_parse_args( $args, $defaults ); woocommerce_get_template( 'cart/mini-cart.php', $args ); } }
Thanks to that function_exists()
check, we are actually given the opportunity to “plug-in” our own function implementation before this one is loaded; hence the term “pluggable”. We can do so by simply copying this function to our theme’s functions.php
and making whatever changes we might want, including loading the same or perhaps an entirely different template file.
Keep in mind that not all WooCommerce widgets are structured to use template functions and files, so you’ll have to actually look at the code for the widget in question and determine whether this override option is available to you. If it is, and allows you to do what you need, that’s great as like the previous options it’s very easy, safe, and doesn’t impact WooCommerce upgrades.
Option 5 – Subclass, modify and register a widget
Among the benefits of this option are: the fact that we can do this with any widget regardless of whether it uses a pluggable template function, by subclassing we can inherit some behavior while overriding other, we can change anything about the plugin’s behavior, and this is quite upgrade-safe. That is unless your child class depends on a part of the parent widget implementation which happens to change in a subsequent release; something that is possible but probably unlikely, and could be addressed with the final option, described after this one.
The basic recipe for the subclass method is as follows:
- Subclass the widget in question in a new widget class, changing whatever functionality you desire.
- Unregister the widget in question
- Register your new widget
- Use the new widget!
As an example, lets say we want to change the WooCommerce Best Sellers widget, which displays a list of the best selling products on your site. What we want to change about this widget is immaterial, the basic steps will remain the same. First we take a look at the widget code, which can be found at woocommerce/widgets/widget-best_seller.php
to determine whether we can use one of the more preferred modes of overriding described above. It’s pretty obvious that the bulk of code, both for accessing the database, as well as rendering the best sellers list, is contained right within the widget()
method, and with no real filter/action hooks, options 1-4 are out. In addition to the widget()
method, there are a number of other methods such as the constructor and widget form display, which perhaps we don’t care about changing, hence making a subclass the ideal solution as we can rely on the parent for the implementation of those methods, and focus on just changing the main widget()
method to do whatever it is we need.
So we’ll start by creating a new file in our theme named: my-theme/widgets/widget-best_sellers.php
, and containing a new class class that extends WooCommerce_Widget_Best_Sellers
and copying in the entire widget()
method from woocommerce/widgets/widget-best_seller.php
:
class Custom_WooCommerce_Widget_Best_Sellers extends WooCommerce_Widget_Best_Sellers { function widget( $args, $instance ) { // copy the widget function from woocommerce/widgets/widget-best_seller.php } }
Then add the following code to your theme’s functions.php
to unregister the WooCommerce Best Sellers widget and register our custom one in its place:
add_action( 'widgets_init', 'override_woocommerce_widgets', 15 ); function override_woocommerce_widgets() { // Ensure our parent class exists to avoid fatal error (thanks Wilgert!) if ( class_exists( 'WooCommerce_Widget_Best_Sellers' ) ) { unregister_widget( 'WooCommerce_Widget_Best_Sellers' ); include_once( 'widgets/widget-best_sellers.php' ); register_widget( 'Custom_WooCommerce_Widget_Best_Sellers' ); } }
Now you’ll be able to use this new widget in exactly the same manner as the old one, and change any of the functionality you need in the widget()
method. There will be no confusion in the admin UI as there will only be one version of the Best Sellers widget shown; your custom version. Future updates of WooCommerce should be relatively painless as you haven’t actually modified any core files.
Option 6 – Duplicate, modify and register a widget
This approach is exactly the same as option 5, except you’ll need to copy the entire parent widget file over, and you won’t be extending from it as we did in the previous option. Here we’re literally creating an entirely new widget and swapping it in place of the old, so it’s fairly brute force, but on the other hand does not rely on any implementation details of the original widget. The same basic code is used to unregister and register the widgets.
Conclusion
And so there you have it, 6 different ways of seamlessly and safely modifying widget behavior. I’d be curious to hear if you end up overriding any widgets, WooCommerce or otherwise, which widgets you change and what for; let me know in the comments section below!
The post How to Override WooCommerce Widgets appeared first on Fox Run Software.