3

I'm trying to display the Woocommerce nav filters on the home page so visitors can filter all the shop products from any page (when they hit the filter they will be taken to the shop page as usual). What I wanted is to include it on the header to accomplish this but it doesn't work.

To my understanding it loads only when the shop loop is loaded. I tried to do a custom loop but that didn't work.

2

I didn't found any documentation at all on how to do this. So here comes the work arround that worked for me.

  1. Register a sidebar in the functions.php file (you can change the name to whatever you want):

    function meir_widgets_init() {
        register_sidebar( array(
            'name' => 'Filters Sidebar',
            'id' => 'filters-sidebar',
            'description' => 'Sidebar for top filters.',
            'before_widget' => '<div id="%1$s" class="widget %2$s">',
            'after_widget' => '<div class="clear"></div></div></div></div>',
            'before_title' => '<h3 class="widget-title">',
            'after_title' => '</h3><div class="filter_box"><div class="filter_wrapper">',
        ) );
    add_action( 'widgets_init', 'meir_widgets_init' );
    
  2. At the end of the functions.php file:

    if (!is_admin()) {
    function woocommerce_price_filter_init2() {
        global $woocommerce;
    
        //if ( is_active_widget( false, false, 'price_filter', true ) && ! is_admin() ) {
    
            $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
    
            wp_register_script( 'wc-price-slider', plugins_url('/woocommerce/assets/js/frontend/price-slider' . $suffix . '.js', __FILE__));
            wp_enqueue_script('wc-price-slider','',true);
    //      array( 'jquery-ui-slider' ), '1.6', true );
    
        wp_enqueue_script('jquery-ui-slider', false, array('jquery'), false, true);
    
            add_filter( 'loop_shop_post_in', 'woocommerce_price_filter' );
        //}
    }
    
    add_action( 'init', 'woocommerce_price_filter_init2' );
    }
    
    
    function my_plugin_body_class($classes) {
        $classes[] = 'woocommerce';
        $classes[] = 'woocommerce-page';
        return $classes;
    }
    
    add_filter('body_class', 'my_plugin_body_class');
    
  3. After that Create a folder inside your template named cache-woocommerce-nav-filter

  4. In the template page you want to display the custom filters (our sidebar in this case is named filters-sidebar but can be change to anything else:

    if(!function_exists('dynamic_sidebar')){
    
            }
    
            else{
    
                $hrcachfold = plugin_dir_path( __FILE__ )."cache-woocommerce-nav-filter/";
                $hrcachefile = $hrcachfold.date("YmdH")."-cache.php";
                $shop_page_url = get_permalink( woocommerce_get_page_id( 'shop' ) );
                $actual_link = "http://".$_SERVER["HTTP_HOST"].$_SERVER["REQUEST_URI"];
    
                if ( is_shop() ) {
                    if ( ($actual_link == $shop_page_url) AND !file_exists($hrcachefile) ) {
    
                        foreach ( glob ( $hrcachfold."*-cache.php" ) as $v ) {
                            unlink ($v);
                        }
    
                        ob_start();
    
                        dynamic_sidebar('filters-sidebar');
    
                        $content = ob_get_contents();
    
                        $f = fopen( $hrcachefile, "w" );
    
                        fwrite( $f, $content );
    
                        fclose($f);ob_end_clean();
                    }
    
                    dynamic_sidebar('filters-sidebar');         
                }
    
                else {
    
                    $shoppage = file_get_contents($shop_page_url);
    
                    if ( ($actual_link == $shop_page_url) AND !file_exists($hrcachefile) ) {
    
                        foreach ( glob ( $hrcachfold."*-cache.php" ) as $v ) {
    
                            unlink ($v);
    
                        }
    
                        ob_start();
    
                        dynamic_sidebar('filters-sidebar');
    
                        $content = ob_get_contents();
    
                        $f = fopen ( $hrcachefile, "w" );
    
                        fwrite( $f, $content );
    
                        fclose ($f);
    
                        ob_end_clean();
                    }
    
                    include($hrcachefile);
                }
    
            }
    
| improve this answer | |
1

look for this piece of code in wp-content/plugins/woocommerce/classes/widgets

if ( ! is_post_type_archive( 'product' ) && is_array( $_attributes_array ) && ! is_tax( array_merge( $_attributes_array, array( 'product_cat', 'product_tag' ) ) ) )
            return;

AND REMOVE IT.

Yur widget should now display on every page

| improve this answer | |
  • Hi thanks for your reply. I did removed it but it still doesn't display anything – Gman Sep 3 '13 at 14:53
0

I have just had the same problem, and here is how I solved it. As the OP stated, the real problem here is that WC filters work only when the main query is loaded with the products. So, calling do_action( 'woocommerce_sidebar' ); without proper global WP_Query and WC_Query loaded will most often do nothing.

So I created this helper function:

<?php
function wpse112648_woo_sidebar() {
    global $wp_query;

    // Get our products
    $wp_query = new WP_Query( [
        'cache_results' => 1,
        'post_type' => 'product',
        'tax_query' => [
            'relation' => 'AND',
            [
                'taxonomy' => 'product_visibility',
                'field'    => 'term_taxonomy_id',
                'terms'    => [
                    13,
                ],
                'operator' => 'NOT IN'
            ],
        ],
    ] );

    // Load the WC instance with our query
    wc()->query->product_query( $wp_query );

    // Call our sidebar
    do_action( 'woocommerce_sidebar' ); // or: dynamic_sidebar('your-registered-sidebar');

    // Cover our tracks
    wp_reset_query();
}

Now, on every page template you want to display your sidebar, just call this function: wpse112648_woo_sidebar()

| improve this answer | |

Not the answer you're looking for? Browse other questions tagged or ask your own question.