Thank you! Your feedback has been delivered
Thank you! Your feedback has been sent

Get terms, then filter terms to see if in another taxonomy

Sorry in advance this is hard to explain but I think should be pretty easy to do. This is the PHP code I have right now and it works, no errors, but I need it to do more:

$terms = get_terms('member_tax', 'hide_empty=1');
$count = count($terms);
if ( $count > 0 ) {
    echo '<ul id="filters" class="option-set clearfix">';
    echo '<li><a href="#all" data-filter="*">All Listings</a></li>';
foreach ( $terms as $term ) {
    $termname = strtolower($term->name); 
    $strippers = array(" ", "&amp;"); 
    $termname = str_replace($strippers, '', $termname);  
    echo '<li><a href="#accomm-filters" data-filter="' . '.' . $termname . '">' . $term->name . '</a></li>';
}
echo '<li><a href="#hidden" data-filter="hidden">Hide Listings</a></li></ul>';
}

This enables me to produce a nice list of all terms used within the member_tax custom taxonomy. However, I essentially want to filter this list of terms so it only displays the terms that are in member_tax if another another separate taxonomy is also selected.

Ex: snippet above should get_terms() of member_tax if another custom taxonomy colour_tax has the colour "purple" selected.

Note, I already have the value (slug) of the other taxonomy I need to filter the get_terms by on the page, I just need a way to do this filtering.

Thanks!!

User Gravatar

creativelogic

Posted Feb 10 2014 16:58 UTC

$30


  • Assigned To tripflex
  • Solved
  • php
    wordpress
    taxonomies
  • 6687 Views

8 Replies


Hi,

you can't do that directly because there is no relation between terms from a taxonomy and another. However, you can obtain a similar result by getting all posts with terms from both taxonomies and then use their ids to get terms.

// First we get all posts with both taxonomies (this is the only way to obtain a relation between terms)
$posts_ids = get_posts(array(
    "fields"    => "ids",
    "tax_query" => array(
        "relation" => "AND", // important
        array(
            "taxonomy" => "member_tax",
            "field"    => "slug",
            "terms"    => "member_tax_term_slug", // Replace with a term from member_tax
        ),
        array(
            "taxonomy" => "other_taxonomy",
            "field"    => "slug",
            "terms"    => "other_tax_term_slug", // Replace with a term from the other tax
        )
    )
));

// then we use all post ids to get terms from the other taxonomy
if(!empty($posts_ids)){
    $terms = wp_get_object_terms( $posts_ids, "other_tax" ); // replace "other_tax" with terms to retrieve from the other tax

    if(!empty($terms) && !is_wp_error($terms)){
        // do all you want with your terms
    }
}
User Gravatar

fulippo

Posted Feb 11 2014 1:38 UTC

Hi, thanks for the help so far! Definitely I could not get the above to work. And my code works, but it needs one tweak please! By the way not sure was the "fields" => "ids" is supposed to do in the get_posts function?

Anyway, this is what I have now and everything works, except wp_get_object_terms returns each and every term, so I get the same filter/list item returned multiple times when I only need each one used ONCE. Any thoughts?

$taxonomy = 'member_tax'; // this is the name of the taxonomy
$terms = get_terms( $taxonomy, 'orderby=count&hide_empty=1' );
$args = array( 
    'posts_per_page' => -1, 
    'post_type' => 'members_type', 
    'tax_query' => array(
    'relation' => 'AND',
            array(
                'taxonomy' => 'accomm_cat',
                'field' => 'slug',
                'terms' => $category_slug
            ),
            array(
                'taxonomy' => 'member_tax',
                'field' => 'slug',
                'terms' => m_explode($terms,'slug')
            )   
        )
);

$tax_query = get_posts($args);
$post_ids = wp_list_pluck( $tax_query,'ID' );
$filter_terms = wp_get_object_terms($post_ids, 'member_tax');

if(!empty($filter_terms)){
    if(!is_wp_error( $filter_terms )){
        echo '<ul id="filters" class="option-set clearfix">';
        foreach($filter_terms as $term){
            $termname = strtolower($term->name); 
            $strippers = array(" ", "&amp;"); 
            $termname = str_replace($strippers, '', $termname);  
            echo '<li><a href="#accomm-filters" data-filter="' . '.' . $termname . '">' . $term->name . '</a></li>'; 
        }
        echo '</ul>';
    }
}
User Gravatar

creativelogic

Posted Feb 11 2014 17:06 UTC

The "fields" => "ids" is specifying in the arguments that is the field you want. Basically instead of using wp_list_pluck as now you are calling an extra function.

Look at the bottom of the page:

http://codex.wordpress.org/Template_Tags/get_posts

I'm a bit confused as to what it is you actually want, maybe give a better descrption/example of output...

User Gravatar

tripflex

Posted Feb 14 2014 18:23 UTC

Let's try using an example.

I have two custom taxonomies, cities and accommodation type. So for let's a say a hotels page I need to query for all HOTELS to general list of cities with hotels. That way I can use the list that's generate for isotope filters.

What I have above in my last post works, EXCEPT, it of course just displays all filter terms each time there is a post in the query with them. So I get a list like this:

  • City Alpha
  • City Beta
  • City Alpha
  • City Alpha

When really I must only have a list with:

  • City Alpha
  • City Beta

Hopefully that helps to explain it better. I was thinking something like array_unique() would solve the issue, but it errors out as "Object of class stdClass could not be converted to string".

User Gravatar

creativelogic

Posted Feb 15 2014 8:45 UTC

I think I understand what you're trying to do, and without doing any testing or looking for better methods to accomplish this, I think the code below should solve the problem based off what you already have.

To break it down, I just changed the code to create a new array of the terms that are found, but the array only adds the term to the existing array if it does not exist. Then after that just use another for loop to generate the list items based off that array that we created.

Good luck, let me know how it goes!

$taxonomy = 'member_tax'; // this is the name of the taxonomy
$terms = get_terms( $taxonomy, 'orderby=count&hide_empty=1' );
$args = array(
    'posts_per_page' => -1,
    'post_type' => 'members_type',
    'tax_query' => array(
    'relation' => 'AND',
            array(
                'taxonomy' => 'accomm_cat',
                'field' => 'slug',
                'terms' => $category_slug
            ),
            array(
                'taxonomy' => 'member_tax',
                'field' => 'slug',
                'terms' => m_explode($terms,'slug')
            )
        )
);

$tax_query = get_posts($args);
$post_ids = wp_list_pluck( $tax_query,'ID' );
$filter_terms = wp_get_object_terms($post_ids, 'member_tax');

$tax_query = get_posts($args);
$post_ids = wp_list_pluck($tax_query, 'ID');
$filter_terms = wp_get_object_terms($post_ids, 'member_tax');

if (!empty($filter_terms)) {
    if (!is_wp_error($filter_terms)) {
        // Create new empty array
        $foundterms = array();
        foreach ($filter_terms as $term) {
            // Check if the term is already in the array, if not, add it to the array
            if (!in_array($foundterms, $term->name) array_push($foundterms, $term->name);
        }
        // Start our UL HTML output
        echo '<ul id="filters" class="option-set clearfix">';
        foreach ($foundterms as $eachterm) {
            // Generate HTML for each LI based off the array we created above
            echo '<li><a href="#accomm-filters" data-filter="' . '.' . strtolower($eachterm) . '">' . $eachterm . '</a></li>';
        }
        // Close our UL HTML tag
        echo '</ul>';
    }
}
User Gravatar

tripflex

Posted Feb 15 2014 21:34 UTC

Solution

This didn't solve your task? Get your own custom solution.

Makes sense and it works. Not sure if it's the most optimal solution, but certainly it works. A few side notes...

Looks like you had the needle and haystack reversed so I was getting a PHP error for the in_array() function. I just switched those around and all was good.

Also, if (!in_array($foundterms, $term->name) is missing a closing parenthesis.

And you accidentally duplicated the $tax_query = get_posts($args).

User Gravatar

creativelogic

Posted Feb 16 2014 7:46 UTC

haha yeah sorry, had to copy and paste the code back and forth from sublime text and must have missed that during the edits, also was writing the code without error checking or looking up any of the functions as I changed it around about 5 times before actually understanding what needed to be done :) lol

It's actually very simple but for some reason I had a hard time getting my head around what exactly needed to be done (functionality wise). But either way glad it works, good luck!

User Gravatar

tripflex

Posted Feb 16 2014 11:54 UTC

Hello. Good wordpress plugin to search by meta fields and taxonomies with built-in meta fields constructor WordPress Meta Data & Taxonomy Filter. Get it here: http://codecanyon.net/item/wordpress-meta-data-filter/7002700?ref=realmag777

User Gravatar

user1516

Posted Mar 26 2014 15:25 UTC

Add a reply

By posting a reply on CodersClan you agree to our Terms & Conditions