Stefan Malic
Stefan Malic

Reputation: 71

Woocommerce - overriding the template through a plugin

I have a question: is there a way to override WooCommerce's default template through a plugin the same way you'd do it with a theme? I have this code:

Class WoocommerceOverride {

    public function woocommerce_locate_template( $template, $template_name, $template_path ) {
        $plugin_path = SPSL_PLUGIN_PATH;
        global $woocommerce;
        $_template = $template;
        if ( ! $template_path ) $template_path = $woocommerce->template_url;
        $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;

        //echo $template."<br>";

  // Return what we found
        return $template;
    }

}
add_filter( 'woocommerce_locate_template', array('WoocommerceOverride', 'woocommerce_locate_template'), 10, 3 );

The problem with this code is that it works only partially. On some parts it works, on other parts it does not. For example, I can't customize archive-product.php at all. Whatever I write in there, whether code or plain text, I just don't get any results. I copied the exact same template files from my plugin folder into my theme folder and it works. However, as I need this as a plugin, I can't go the theme route.

Many thanks.

Upvotes: 7

Views: 6979

Answers (3)

Tahi Reu
Tahi Reu

Reputation: 590

You should try adding this code before your // Use default template code:

if( $template_name == '{template part name}') {
     $template = $plugin_path . $template_name;
}

In my case {template part name} was global/quantity-input.php

You can find out your exact template part names by temporary adding this line to your code:

print_r($template_name);

I know it's a bit late for answer here but maybe it will be useful for someone else. And keep in mind woocommerce_locate_template is depricated. So there is probably more 'up to date' solution somewhere out there.

Upvotes: 0

maheshwaghmare
maheshwaghmare

Reputation: 2192

  • Using filters wc_get_template_part we can override default WooCommerce template part's.
  • Using filters woocommerce_locate_template we can override default WooCommerce template's.

Try below example code snippet.

<?php
/**
 * Override default WooCommerce templates and template parts from plugin.
 * 
 * E.g.
 * Override template 'woocommerce/loop/result-count.php' with 'my-plugin/woocommerce/loop/result-count.php'.
 * Override template part 'woocommerce/content-product.php' with 'my-plugin/woocommerce/content-product.php'.
 *
 * Note: We used folder name 'woocommerce' in plugin to override all woocommerce templates and template parts.
 * You can change it as per your requirement.
 */
// Override Template Part's.
add_filter( 'wc_get_template_part',             'override_woocommerce_template_part', 10, 3 );
// Override Template's.
add_filter( 'woocommerce_locate_template',      'override_woocommerce_template', 10, 3 );
/**
 * Template Part's
 *
 * @param  string $template Default template file path.
 * @param  string $slug     Template file slug.
 * @param  string $name     Template file name.
 * @return string           Return the template part from plugin.
 */
function override_woocommerce_template_part( $template, $slug, $name ) {
    // UNCOMMENT FOR @DEBUGGING
    // echo '<pre>';
    // echo 'template: ' . $template . '<br/>';
    // echo 'slug: ' . $slug . '<br/>';
    // echo 'name: ' . $name . '<br/>';
    // echo '</pre>';
    // Template directory.
    // E.g. /wp-content/plugins/my-plugin/woocommerce/
    $template_directory = untrailingslashit( plugin_dir_path( __FILE__ ) ) . 'woocommerce/';
    if ( $name ) {
        $path = $template_directory . "{$slug}-{$name}.php";
    } else {
        $path = $template_directory . "{$slug}.php";
    }
    return file_exists( $path ) ? $path : $template;
}
/**
 * Template File
 *
 * @param  string $template      Default template file  path.
 * @param  string $template_name Template file name.
 * @param  string $template_path Template file directory file path.
 * @return string                Return the template file from plugin.
 */
function override_woocommerce_template( $template, $template_name, $template_path ) {
    // UNCOMMENT FOR @DEBUGGING
    // echo '<pre>';
    // echo 'template: ' . $template . '<br/>';
    // echo 'template_name: ' . $template_name . '<br/>';
    // echo 'template_path: ' . $template_path . '<br/>';
    // echo '</pre>';
    // Template directory.
    // E.g. /wp-content/plugins/my-plugin/woocommerce/
    $template_directory = untrailingslashit( plugin_dir_path( __FILE__ ) ) . 'woocommerce/';
    $path = $template_directory . $template_name;
    return file_exists( $path ) ? $path : $template;
}

Upvotes: 17

Domain
Domain

Reputation: 11808

Few months ago the i had the same requirements. So searched a bit more on the net and found useful code which helped me(with a little more customization as per my requirements).

For a detailed code with explanation check this and this link. The approach might be different than what you currently using but it results in overriding woocommerce templates in plugin

Upvotes: 0

Related Questions