sage-woocommerce icon indicating copy to clipboard operation
sage-woocommerce copied to clipboard

Issues with custom taxonomy for product category using sage-woocommerce

Open ghost opened this issue 6 years ago • 8 comments

Submit a feature request or bug report

What is the current behavior?

If I create a new product category called "test" and I create a new file under the folder woocoomerce for override this product category archive it doesn't work.

I've created the file taxonomy-product_cat-test.blade.php and it's not loading. I've tried to reproduce with the same steps on a non-sage installation and works perfect. I think the issue is related with the action of template-loader.

What is the expected or desired behavior?

It should allow you create a custom taxonomy file like a normal Wordpress/Wooocommerce installation so you can override templates.


Bug report

Please provide steps to reproduce, including full log output:

Steps to reproduce:

  1. Create a new product category
  2. Create a file to override this product category under woocommerce folder: taxonomy-product_cat-{slug}.blade.php
  3. Access the product category view, it should load your custom template.

PS: I've tested on a non-sage installation and it worked. So it definitely should be something with the load-template action.

Please describe your local environment:

WordPress version: 4.9

OS: Windows 10

NPM/Node version: 10

Where did the bug happen? Development or remote servers?

Both

ghost avatar Feb 26 '19 02:02 ghost

Thanks for reporting, @talkagency.

@mejta is this something you're interested in looking into?

mmirus avatar Feb 27 '19 17:02 mmirus

@mmirus hi, sorry for that, but at the moment I'm thoroughly hooked into another project with tight deadline, so in following days I cannot support that.

mejta avatar Feb 28 '19 22:02 mejta

@mmirus One curious thing, the function wc_get_template( 'myaccount/dealer-videos.php' ) only is looking inside the woocommerce plugin at the templates folder. The normal action for this folder is basically: "Try to find at the plugin folder, if don't find, then try on the theme one. So what should happen in this case is to try to find at the Sage Woocomerce folder instead.

ghost avatar Mar 09 '19 04:03 ghost

Same problem. I've tried creating both of these: woocommerce/taxonomy-product_cat-mycategory.blade.php woocommerce/taxonomy-product_cat-mycategory.php but it has no effect.

In my case I can work around it by using some conditional logic in my archive-product.blade.php file:

@php
$query_object = get_queried_object();
@endphp

@if(isset($query_object->slug) && ($query_object->slug == 'mycategory'))
	{{-- Category code --}}
@endif

but that won't be great in a lot of situations.

stuartcusackie avatar Oct 12 '19 16:10 stuartcusackie

Just in addition to this, a similar problem is occurring with product attribute templates.

For example, my products have a 'group' attribute. I'm pretty sure on a standard WordPress installation you could override this like so: /woocommerce/taxonomy-pa-group.php

But this doesn't seem to have an effect in sage-woocommerce: /woocommerce/taxonomy-pa-group.blade.php

stuartcusackie avatar Oct 30 '19 10:10 stuartcusackie

I appear to be running in to this issue too. archive-product.blade.php is being used instead of my taxonomy-product_platform.blade.php file.

jordan26 avatar Mar 27 '20 17:03 jordan26

same same; I can report the same misbehaviour: archive-product.blade.php is overriding everything (except non-blade templates in resources as stated above); using @stuartcusackie work-round works but I have a bad feeling ab

jrgd avatar Apr 28 '20 16:04 jrgd

This issue seems to be caused by WC_Template_Loader::template_loader (executed as a template_include filter) which overrides the Blade template path being filtered. If a product related template is being displayed, this method will change the template with its own templates hierarchy logic (see WC_Template_Loader::get_template_loader_files). It then fallbacks to the archive-product.php template since it only searched for the existence of template paths like taxonomy-YOUR_CUSTOM_TAX.php and not taxonomy-YOUR_CUSTOM_TAX.blade.php. Then, sage-woocommerce changes the template path to archive-product.blade.php.

A more robust workaround could be to hook on the woocommerce_template_loader_files filter and add your own Blade template path depending on the taxonomy, for instance :

add_filter('woocommerce_template_loader_files', function ($templates, $default_file) {
    if (is_tax('YOUR_CUSTOM_PRODUCT_TAX')) {
        $templates[] = 'views/taxonomy-YOUR_CUSTOM_PRODUCT_TAX.blade.php';
        // or
        // $templates[] = 'views/' . WC()->template_path() . 'taxonomy-YOUR_CUSTOM_PRODUCT_TAX.blade.php';
    }

    if (is_tax('YOUR_OTHER_CUSTOM_PRODUCT_TAX')) {
        $templates[] = 'views/taxonomy-YOUR_OTHER_CUSTOM_PRODUCT_TAX.blade.php';
        // or
        // $templates[] = 'views/' . WC()->template_path() . 'taxonomy-YOUR_OTHER_CUSTOM_PRODUCT_TAX.blade.php';
    }

    return $templates;
}, 10, 2);

Maybe this package could be updated to use this filter by adding the following (NOT TESTED) :

    // Logic taken from WC_Template_Loader::get_template_loader_files (private method)
    // Lines that unnecessary (IMO) are commented out
    // but let me know if you find a case where it turns out that they are needed
    add_filter('woocommerce_template_loader_files', function ($templates, $default_file) {
        // Not sure the following line is necessary for sage-woocommerce
//         $templates[] = 'woocommerce.php';

        // Not sure the following lines are necessary for sage-woocommerce
//        if ( is_page_template() ) {
//            $page_template = get_page_template_slug();
//
//            if ( $page_template ) {
//                $validated_file = validate_file( $page_template );
//                if ( 0 === $validated_file ) {
//                    $templates[] = $page_template;
//                } else {
//                    error_log( "WooCommerce: Unable to validate template path: \"$page_template\". Error Code: $validated_file." );
//                }
//            }
//        }

        if (is_singular('product')) {
            $object = get_queried_object();
            $name_decoded = urldecode($object->post_name);
            if ($name_decoded !== $object->post_name) {
                $templates[] = "views/single-product-{$name_decoded}.blade.php";
            }
            $templates[] = "views/single-product-{$object->post_name}.blade.php";
        }

        if (is_product_taxonomy()) {
            $object = get_queried_object();
            $templates[] = 'views/taxonomy-' . $object->taxonomy . '-' . $object->slug . '.blade.php';
            $templates[] = 'views/' . WC()->template_path() . 'taxonomy-' . $object->taxonomy . '-' . $object->slug . '.blade.php';
            $templates[] = 'views/taxonomy-' . $object->taxonomy . '.blade.php';
            $templates[] = 'views/' . WC()->template_path() . 'taxonomy-' . $object->taxonomy . '.blade.php';
        }

        // Not sure the following lines are necessary for sage-woocommerce
//        $templates[] = $default_file;
//        $templates[] = WC()->template_path() . $default_file;

        return array_unique($templates);
    }, 10, 2);

This would require the maintainers of this repo to watch for any changes of logic in the WC_Template_Loader::get_template_loader_files, then to copy them with the Blade extensions.

I did not find an easier way since the WC_Template_Loader::get_template_loader_files method is private and no filter is applied at the end of this method. Let me know if anyone finds a more clever way or if you want me to open a PR with the code above.

Hope this'll help !

JoeCrescoll avatar May 11 '20 23:05 JoeCrescoll