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.
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.
Share Improve this question edited Sep 3, 2013 at 8:27 shea 5,6624 gold badges39 silver badges62 bronze badges asked Sep 3, 2013 at 2:31 GmanGman 1832 silver badges11 bronze badges 03 Answers
Reset to default 2I didn't found any documentation at all on how to do this. So here comes the work arround that worked for me.
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' );
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');
After that Create a folder inside your template named
cache-woocommerce-nav-filter
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); } }
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
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()