1

Sorry about the title I do not know how to put the question in the form of a title very well but my question if very descriptive.

Iv been meaning to asking this question for a while now and would really! like to know so im going to be as descriptive and detailed as I possibly can. Let me start of by letting you know what the situation is and how things are working.

I have one Custom Post Type of "Products" created by the Custom Post Type UI Plugin

Along with two custom Taxonomies of "Types" and "Countries" used as filters for my products in my Taxonomy.php

Ok so now that you understand the set up this is what im doing, lets say I have a shirt store and I am filtering through my products based on "Countries" and "Types"

Countries:

  • USA

  • China

  • France

Types:

  • Cotton

  • Silk

  • Polyester

Now on my taxonomy.php where I list all custom post types of products on the left I have a list of all of my Countries and Types so people can filter through them and see the appropriate products.

The problem:

When I go into my shirts page where I see ALL of my shirts I can see on the left side the "Types" so lets say I then click on the type of cotton now I can see all of my custom post types of products that are cotton which is great but now this is the problem. When im on the cotton term of the taxonomy Types I can see my countries terms on the left and when I click on lets say USA I see ALL of the Products listed under the term of USA But thats NOT what I want. I wanted it so that when im on cotton and then click on the Country Term of USA I will only see products of cotton with the the Country Term of USA NOT all of the products under the term of USA.

My code in functions.php for my products in my taxonomy page to display properly with paginations:

add_action( 'pre_get_posts', function ( $q ) {
    if( !is_admin() && $q->is_main_query() && $q->is_tax() ) {
        $q->set( 'posts_per_page', 2 );
        $q->set( 'orderby', 'name' );
        $q->set( 'order', 'ASC' );
    }
});

Then in my taxonomy.php I have my products and my custom taxonomy filters on the left set up like so:

// listing all of my Types Terms of the current term on the left using it as filters for my shirts.
<div class="categories types">
<p>Types</p>
<ul>
<?php

//get the current term
$current_term = get_term_by( 'slug', get_query_var( 'term' ), get_query_var( 'taxonomy' ) );

//then set the args for wp_list_categories
 $args = array(
  'child_of' => $current_term->term_id,
  'taxonomy' => 'types',
  'hide_empty' => 1,
  'order'      => 'ASC',
  'show_count'     => 1,
  'hierarchical' => true,
  'depth'  => 1,
  'title_li' => ''
    );
 wp_list_categories( $args );
?>
</ul>

</div><!--categories end-->



// listing all of my Types Terms of the current term on the left using it as filters for my shirts.
<div class="categories countries">
<p>Types</p>
<ul>
<?php

//get the current term
$current_term = get_term_by( 'slug', get_query_var( 'term' ), get_query_var( 'taxonomy' ) );

//then set the args for wp_list_categories
 $args = array(
  'child_of' => $current_term->term_id,
  'taxonomy' => 'countries',
  'hide_empty' => 1,
  'order'      => 'ASC',
  'show_count'     => 1,
  'hierarchical' => true,
  'depth'  => 1,
  'title_li' => ''
    );
 wp_list_categories( $args );
?>
</ul>

</div><!--categories end-->



//listing my products custom post types
<div class="products">

<?php while( have_posts() ) : the_post(); ?>

//the loop
<?php the_field('title'); ?>
<?php the_field('image'); ?>

<?php endwhile; ?>

//pagination
<?php 
global $wp_query;

$total_pages = $wp_query->max_num_pages;

if ($total_pages > 1){

  $current_page = max(1, get_query_var('paged'));

  echo paginate_links(array(
      'base' => get_pagenum_link(1) . '%_%',
      'format' => '/page/%#%',
      'current' => $current_page,
      'total' => $total_pages,
      'before_page_number' => '<div class="pagination-navigation">',
      'after_page_number' => '</div>'

    ));
}
?>

</div><!--products end-->

So as you can see above that is my functions.php and my taxonomy.php.

So I have been thinking a lot about this and what logic I can use and iv only come up with maybe one way this is possible. So my taxonomy of Countries is the problem because when I click on a country like USA I want to see the countries of the previous term I was on which was cotton and NOT all of the countries under USA.

Sorry for the long explanation but CLICK HERE to visually see what I want to achieve and you will fully understand it.

1

When you use wp_list_categories() you get a list of terms, each one linked to its archive page. I think what you need is a form to filter the products, not a list of archive term links, so you can keep the selected filters between requests, for example, using $_POST, $_SESSION or $_COOKIES.

Example using $_POST:

<?php
//taxonomies you want to filter
$taxonomies = array( "countries", "types" );
function get_terms_dropdown($taxonomy, $args){
    $terms = get_terms($taxonomy, $args);
    $output = '<select id="'.$taxonomy.'" name="'.$args['name'].'" multiple>';
    foreach($terms as $term){
        in_array($term->term_id, $args['selected']) ? $sel = ' selected' : $sel = '';
        $output .='<option value="'.$term->term_id.'"'.$sel.'>'.$term->name.'</option>';
    }
    $output .="</select>";
    return $output;
}
?>
<?php
//Set the action of the from to custom post type archive
?>
<form method="post" action="<?php echo get_post_type_archive_link('products');?>" id="products-filter-form">
<?php
foreach($taxonomies as $taxonomy) {
    //check if there is a previously selected terms
    $selected = (!empty($_POST['tax_input'][$taxonomy])) ? ($_POST['tax_input'][$taxonomy]) : array();
    $selected = array_map('intval', $selected);

    $args = array(
         'hide_empty' => false,
         'selected'   => $selected,
         'name'       => 'tax_input['.$taxonomy.'][]',
    );
    echo get_terms_dropdown($taxonomy,$args);
}
?>
<button type="submit">Filter</button>
<button type="reset" value="reset">Reset</button>
</form>

And now the in the preg_get_posts action you add the selected taxonomy terms to the query:

add_action( 'pre_get_posts', 'cyb_pre_get_post' );
function cyb_pre_get_post($query){

    if($query->is_main_query() && !is_admin() && is_post_type_archive( 'products' ) ) {
        //taxonomies you want to filter
        $taxonomies = array( "countries", "types" );
        $tax_input = isset($_POST['tax_input']) ? $_POST['tax_input'] : '';
        if(!empty($tax_input)){
            //Ready to construct the tax_query
            foreach($taxonomies as $taxonomy) {
                if(isset($tax_input[$taxonomy])) {
                    $value = array_map('intval', $tax_input[$taxonomy]);
                    if(!empty($value) && $value[0] != "0"){
                        $tax_query[] = array(
                            'taxonomy' => $taxonomy,
                            'field' => 'id',
                            'terms' => $value
                        );
                    }
                }
            }
            $query->set('tax_query',$tax_query);
            //The tax_query has been set
        }
    }
}

Note: code tested with category and post_tag taxonomies and it is working. It may need some modifications to fully fit your needs.

  • hmm ok so iv read your code over and over again and tried out some tests and I see where your going with this but I see a lot of problem. One is that the parameters that I have wp_list_categories are no longer working. How would I be able to give that parameters? for instance I want the quantity of posts of that certain category to display to the right of the term. Thats just one parameter that I had but I would need about 4 more parameters meaning it would need to be customizable some how. And on top of that the filters do not work, it stays on the same items. – Lucas Santos Dec 16 '14 at 14:24
  • I dont mean to sounds like im criticizing or anything your code is actually amazing but it changes a lot about how I have everything already set up. – Lucas Santos Dec 16 '14 at 14:26
  • oh and by the way yes the taxonomy is hierarchical – Lucas Santos Dec 16 '14 at 15:14
  • As I said, the code may needs modifications to fully fit your needs. I've tested it with category and post_tag taxonomies and it is working filtering the posts within the selected categories and tags (I posted the code with category and post_tag mixed with your custom taonomies countries and types, I've edited the answer and fixed that typo). Note that in your code you was using get_query_var( 'term' ) and get_query_var( 'taxonomy' ) and in my code the tax query is being modified with the selected terms. – cybmeta Dec 16 '14 at 18:12
  • ok well I can seen a list of all of my countries and types but when I try and filter them nothing happens. it just reloads the page and the items stay the same. – Lucas Santos Dec 17 '14 at 3:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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