Is there a way to display Woocommerce nav filter widget filters for shop page in all headers?

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.

Related posts

3 comments

  1. 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);
                  }
      
              }
      
  2. 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

  3. 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()

Comments are closed.