Custom query filter not working on woocommerce category page

I’m not sure at first glance why this is only working on your home page and not your archive pages, but there are a few things wrong with the way this function is written. So, I’ve rewritten it for you below – using this instead might solve the problem if it was introducing an esoteric bug before.

A couple of things to note:

  • relation should not be used with tax_query when there is only one inner query (reference)
  • your tax_query was three arrays deep – it should only be two
  • as pre_get_posts is an action, there is no return value accepted (in this case, $query is passed by reference, so it doesn’t need returning)
  • "filter" was misspelled as "fillter" (while this wouldn’t have broken the code on its own, it could have mixed you up during testing if you used ?filter= in your query string)
  • I’ve also added sanitisation of the querystring variable you’re bringing in, by way of absint() given it is a term_id

With that said, here’s the simplified function:

function modify_query($query) {
  if( ! is_admin() && $query->is_main_query() && $query->query_vars['post_type'] == 'product') {
    if( isset( $_GET['filter'] ) ) {

      $query->set( 'tax_query', array (
        array(
          'taxonomy' => 'pc_filters',
          'field'    => 'term_id',
          'terms'    => absint( $_GET['filter'] ),
        )
      ));

    }
  }
}

add_action( 'pre_get_posts', 'modify_query' );

I haven’t tested this, but it should do what you were intending in a slightly simpler way, which might solve your problem.

If this doesn’t solve it, it might be due to the query that WooCommerce is using on the archive pages, in particular, the value of query_vars['post_type']. WooCommerce specifics are off-topic here and I’m not actually familiar with it myself, but as far as general WordPress goes, you could use print_r($query->query_vars); within the above function to see what you have to work with, and then modify accordingly. Alternatively, you could remove the post_type check altogether, although then this code would also apply to your general posts and pages which might not be what you’re after.

Leave a Comment