2
votes

We have a Custom Post Type, hr-priority, which has multiple custom taxonomies associated with it. Those taxonomies contain multiple terms and each post can have 1-to-many terms assigned from those taxonomies. We are trying to set up a filter that allows visitors to search/filter results by a combo of those terms, in multiple taxonomies.

For example: The post "Sample Post" has for the taxonomy "year" the term "2018", "org" taxonomy the term "council-member", and "country" taxonomy the term "canada". The post "Other Sample" has for "year" the term "2016", "org" taxonomy the term "manager", and "country" taxonomy the term "canada". The post "Third Post" has for taxonomy "year" the term "2018", "org" taxonomy the term "security-team", and "country" taxonomy the term "iceland".

We want to be able to filter the results by all of those terms, so if I chose to just view the posts from year=2018, I would get "Third Post" and "Sample Post", but then if I further filtered those by country=canada I would only get "Sample Post" (because the filters would be year=2018 and country="canada").

I am using the Search & Filter plugin. I tried using the archive-hr-priority.php template page for the results but that template wasn't recognized in the results at all. I then used the custom taxonomy templates, such as taxonomy-year.php, which did work with just one filter, so when I filtered by year=2018, the only posts returned were from the year 2018, but then when I added a second search term, such as country="canada", it returned all results for the country=canada, but with all year terms.

This is my search&filter shortcode:

echo do_shortcode( '[searchandfilter post_types="hr-priority" fields="year,country"]' );

And this is the code I use in the custom taxonomy templates (I created one for each taxonomy):

if (is_tax() || is_category() || is_tag() ){
        $qObj = get_queried_object();

        $args = array(
            'post_type'=>'hr-priority',
            'tax_query' => array( array(
                  'taxonomy' => $qObj->taxonomy,
                  'field' => 'id',
                  'terms' => $qObj->term_id
                )),
            'post_status'=>'publish',
            'posts_per_page'=>20
        );
    }
    echo($qObj->slug); //just to view the term/s being used
     $wpb_all_query = new WP_Query($args);
    if ( $wpb_all_query->have_posts() ) : ?>
        <?php
        /* Start the Loop */
        while ( $wpb_all_query->have_posts() ) : $wpb_all_query->the_post();

            get_template_part( 'template-parts/post/hr-priorities-post', get_post_format() );

        endwhile;

And this is the URL returned after submitting the Search&Filter paramaters:

https://exampleurl.org/org/council-member?country=afghanistan&post_types=hr-priority-un

How can I get it to filter by multiple terms in multiple taxonomies and return only the results that match ALL of the search parameters?

2

2 Answers

1
votes

I'm not familiar with "Search & Filter", but this looks easy enough to do with base WP_Query. You can search across multiple taxonomies with the following:

$tax_query = array(
  'relation' => 'AND'
);

// get query parameters and compose the condition
$year = $_GET['year'];
if (!empty($year)) {
  $cond = array(
    'taxonomy' => 'year',
    'field' => 'slug',
    'terms' => $year,
  ));
  $tax_query[] = $cond;
}
// Repeat for other parameters

$args = array(
  'post_type'=>'hr-priority',
  'tax_query' => $tax_query,  
  'post_status'=>'publish',
  'posts_per_page'=>20,
);

Reference documentation

0
votes

I figured it out with some answers from a few other questions (see citation list below).

First, I had to grab the full list of terms in each taxonomy I may use (this way, if one tax wasn't being queried, I could supply some value, rather than an empty string, for that tax_query's 'term' => value), which I then turned into slugs (second line below), then I used the get_query_var() function to grab the term being queried from each/any of the taxonomies.

    $allStates = get_terms('country', $args = array('hide_empty' => false));
    $state_names = wp_list_pluck( $allStates, 'slug' );
    $country = (get_query_var('country', $state_names));

Then, I sent the value of get_query_var() into an array for my tax_query (I could've just done this in the $args array but it was easier to read outside of that), but needed to use the 'relation' => 'AND' (as pointed out in another suggested answer) to make sure each of those would be included in the query args:

      $tax_query = array(
      'relation' => 'AND',
      array(
        'taxonomy' => 'country',
        'field' => 'slug',
        'terms' => $country,
      ),
      array(
        'taxonomy' => 'org',
        'field' => 'slug',
        'terms' => $org,
      ),);

After that, it was the same general wp_query():

        $args = array(
            'post_type'=>'hr-priority',
            'tax_query' => $tax_query,
            'post_status'=>'publish',
            'posts_per_page'=>20
        );
//  print_r($tax_query);
     $wp_all_query = new WP_Query($args);
    if ( $wp_all_query->have_posts() ) : ?>

Citation List for Answers Used In Figuring Out the Solution (thanks!): https://wordpress.stackexchange.com/a/35611/146095 https://wordpress.stackexchange.com/a/157167/146095