WooCommerce reviews + tutorials

The goal of this article is to describe one approach to overriding WooCommerce core template files within a custom plugin, such that they can still be overridden by a theme in the typical way. Note that this is similar to but solves a slightly different problem than what we did to create a custom overrideable woocommerce template file in your custom plugin. Overriding a core template in your plugin is something you might want to do if you’re creating a WooCommerce plugin that needs to alter a core template file, and you don’t want to have to supply a separate template file for dropping into the theme, and yet you also want the flexibility of allowing the template to be overridden in the theme. Thankfully WooCommerce’s flexible template loading system offers a lot of control over where template files are loaded from, and allows us to do just this.

The normal WooCommerce template loader searches the following locations in order, until a match is found:

  1. your theme / template path / template name
  2. your theme / template name
  3. default path / template name

We’re going to alter this slightly by injecting a search for the template within our own custom plugin (step 3 below), before finally defaulting to the WooCommerce core templates directory:

  1. your theme / template path / template name
  2. your theme / template name
  3. your plugin / woocommerce / template name
  4. default path / template name

This can be done by adding the following function and filter, which basically duplicates and modifies the behavior of the woocommerce_locate_template() function found within woocommerce-core-functions.php:

function myplugin_plugin_path() {

  // gets the absolute path to this plugin directory

  return untrailingslashit( plugin_dir_path( __FILE__ ) );
}
add_filter( 'woocommerce_locate_template', 'myplugin_woocommerce_locate_template', 10, 3 );



function myplugin_woocommerce_locate_template( $template, $template_name, $template_path ) {
  global $woocommerce;

  $_template = $template;

  if ( ! $template_path ) $template_path = $woocommerce->template_url;

  $plugin_path  = myplugin_plugin_path() . '/woocommerce/';

  // Look within passed path within the theme - this is priority
  $template = locate_template(

    array(
      $template_path . $template_name,
      $template_name
    )
  );

  // Modification: Get the template from this plugin, if it exists
  if ( ! $template && file_exists( $plugin_path . $template_name ) )
    $template = $plugin_path . $template_name;

  // Use default template
  if ( ! $template )
    $template = $_template;

  // Return what we found
  return $template;
}

With that active you can override core template files by placing them in myplugin/woocommerce/. For instance, to override loop/add-to-cart.php, copy that file to your plugin in the following location: myplugin/woocommerce/loop/add-to-cart.php and make your modifications. The theme will still be able to override it, and all other template files will be loaded from WooCommerce or the default path, as normal.

Published by Justin Stern

Justin is one of our co-founders, and is our resident overengineer. He likes to write developer tutorials and make black magic happen in our plugins. He thinks that writing code is a lot easier than writing words.

30 Comments

  1. Hi Justin,

    Would love to see how you’d override widgets!

    Please 😛

    Thank you

    • Hey Louis, thanks for the question. I don’t really have much experience with “overriding widgets”, nor do I think it’s really something you can do as such. My guess is that you’d basically want to take the existing widget code and duplicate it, creating your own custom widget, and then make any modifications you need. Hope this helps

  2. Hi Justin, thanks for your reply, I’ll talk a bit more in the other thread! 😛

  3. Hello Justin,

    One more query. I am developing a website using Emporium theme and the WordPress plugin.

    I need to display a featured products slider on the homepage. Is there a way to override the current style ?

    My website http://takspeedshop.com/

    Or can you please provide me the script so that I can insert it manually in the php files and disable the Current Style.

    Regards,

    Safeer

    • Hey Safeer, I actually haven’t worked with the Emporium style, so I wouldn’t be able to give you exact advice. I do know that in the settings for my Wootique theme, under Wootique > Theme Options > Homepage Settings there’s an option to display a “Slider” containing featured products, does Emporium not have a similar option? If not, perhaps you’d have to override the homepage template, and display a slider; sorry I can’t give you any more specific advice

      • Hey justin,

        Nope, there isnt any option.

        It would be great if you can provide me the code snippet of the slider part from the php.

        Please email me or post it here. Which ever suits you.

        OR will it be possible for me to create a slider using shortcodes ?

        Sorry for disturbing again and again!

        Cheers!

  4. This can also be done by unhooking the template function and adding your own function that calls the woocommerce_get_template() function. Investigating the function reveals that the fourth parameter is the first path location to check. This is what I use in my plugins to call a template

    woocommerce_get_template( 'single-product/price.php', FALSE, FALSE, $this->plugin_path . '/templates/');

    where $this->plugin_path is the path to the plugin that I defined earlier in my class and /templates/ is the folder within my plugin that holds all my woocommerce templates.

    • Yup, very true that’s another excellent solution, which for everyone else following along would just mean defining a function that looks like:

      function woocommerce_template_single_price() {
      woocommerce_get_template( 'single-product/price.php', array(), '', $this->plugin_path . '/templates/');
      }

      From an action that executes before 'init', 25, ie:

      add_action( 'init', 'include_my_template_functions', 20 );

      Where our overridden woocommerce_template_single_price() function is defined within this action

      • Hello Justin I find very interesting your forum.

        I have a question, the “woocommerce_get_template_part” found in woocommerce core function from what I understand is the one that is responsible for loading parts of the template in the templates parents. I have not managed to find a way to load these parts from the template directory of my plugin. Example: myplugin / templates / content-product.php. Is there a way to override this method?

  5. Hi Justin, excellent tutorial 😀

    i’ve question, is it possible to add more dimension unit without editing woocommerce_get_dimension function (under woocommerce-core-functions.php), maybe a way to override the function under theme’s functions.php. thanks

  6. Hi Justin,

    thanks for sharing.. I’ts really awesome tutorial.. 😉

    Btw I want to override content-single-product.php how I can do that?

    it’s work inside loop folder but not in the parent /your-plugin/woocommerce/

    Many Thanks

    • Hmm, well it certainly *should* work the same as any other. Hopefully you’ve managed to get it working by now

  7. Hi there, wondering if you could help me on this.

    I tried to override myaccount.php file directly within woocommerce pluggin but whatever i’ve amended doesn’t seems to be reflected.

    Any idea why?

    Much thanks in advance!

    • Hey Lynn, just make sure you’re the file you’re overriding has the exact same name/folders. The My Account template files are broken down into 6 files, so you’re probably referring to myaccount/my-account.php. Copy that into yourtheme/woocommerce/myaccount/my-account.php and you should be good to go. This is described in my other, related article: How to override woocommerce template files

  8. Hi Justin,

    I want to override the single-product.php and archieve-products.php through the plugin but i am unable to do so can you please guide how we can do this without going to woocommerce core or within the themes.Just want to do this through the plugin.

    thanks

  9. Hey Justin,

    I’ve been trying to implement this to edit the following template /single-product-reviews.php but your code above doesn’t work, it works fine for all template file that are one folder deep for example I’ve tested with single-product/meta.php but not those in the parent folder?

    Any idea?

    Thanks
    Will

    • Make sure you’re placing the single-product-reviews.php file inside a woocommerce directory in the root folder of your theme. It should work properly then 🙂

  10. Hey Justin,

    Nice code this is just what I was trying to do. I was working with a theme which had it’s own woocommerce template files and folder and I needed to override them from a plugin

    To have the plugin be the priority I simply removed ! $template && from the if statement checking the plugin template folder. Is that an ok method to set the plugin templates as the priority? It doesn’t leave a fall back to the themes woocommerce templates. What would be a conditional to fall back to the themes woocommerce template files if the plugin is deactivated? Leaving the default templates for the last priority

    Thanks
    Pete

    • Hey Pete, sounds like you’ve got the right approach here. To detect whether a plugin is activate you can use something like the following: if ( in_array( 'woocommerce/woocommerce.php', get_option( 'active_plugins', array() ) ) ) { ... using of course your particular plugin directory/file name.

  11. How to override single-product template from my custom plugin.. i try all above code but doen’t seems working for me. please help me
    thanks in advance…

    • You’ll want to make sure your filenames are correct — do you get an error message or does it just not override properly?

  12. Hi,
    Thanks for posting 🙂 I tried to customize the shop base page from my plugin based on your idea, looks like it is not working it still loading the default wordpress template. What i am doing is copied all template files and move it into my-plugin folder and use the
    I tried by commenting the archive-product.php from my plugin and checked it not show me as blank(Commenting whole thing should make empty or blank the shop page) it returns the shop page with loading of template files from woocommerce not in my plugin folder is anything i missed.
    http://stackoverflow.com/questions/22727583/woocommerce-load-and-customize-archive-product-php-from-my-plugin-folder

    • Sounds like your template isn’t being loaded, you’ll want to make sure that you’ve got it in the right place and loading properly 🙂

  13. AWESOME blog and help by Justin and colleagues!

    one question – when you say: template files you mean the plugin can only override files located in woocommerce/templates/* , correct?

    then i saw you mentioned there is another way to override woocommerce core files that are not in the /templates/ folder?! (enque the file in functions.php?)

    could you show me the light and give us an example of how to override e.g. /wp-content/plugins/woocommerce/includes/admin/post-types/class-wc-admin-cpt-shop_order.php with a custom version of that file “class-wc-admin-cpt-shop_order.php”?

    I have made the changes i need to that file so i like the shop order table but don’t dare to change the core files and since you mentioned there is a better way, i hope to hear from you!

    Honestly after hours of trying various things, you are indeed my last hope 🙂

    Thank you for your help!
    Tobias

    • Only files in the templates directory can be overridden using this technique — if there are other functions wrapped in if ( function_exists(...) ) then you can override them in your functions.php. Otherwise you’ll need to use the actions/filters provided within WooCommerce to make your changes 🙂

  14. This code doesn’t work for archive-product.php in Version 2.2.4

  15. I’m trying to override the content-single-product.php file. But so far it’s no use. I’ve followed your way and it worked for another file i override. product-image.php. I created woocommerce folder inside my plugin and path for product image file is woocommerce > single-product > product-image.php it works. and the path for content-single-product : woocommerce > content-single-product.php. It’s not working. what am i doing wrong?

  16. Perfect, thank you very much!

  17. How can I get the plugin to override the theme and the woocommerce default templates?

Hmm, looks like this article is over 2 years old! Its content may be outdated, so comments are now closed.