Query multiple custom taxonomy terms in WordPress 2.8?

I created a custom taxonomy named ‘technologies’ but cannot query multiple terms like I can with categories or tags.

These querys DO work:

Read More
query_posts('tag=goldfish,airplanes');

query_posts('technologies=php');

However, neither of the following work correctly:

query_posts('technologies=php,sql');

query_posts('technologies=php&technologies=sql');

My objective: Show all posts with a technology of ‘php’ and all posts with a technology of ‘sql’

Any ideas? Is this even possible? Thanks!

Related posts

Leave a Reply

9 comments

  1. Apparently query_posts cannot help in this specific situation. (Hopefully it will be added in future versions of WordPress!) The solution is to use a custom select query like the following:

    SELECT * 
    FROM $wpdb->posts
    LEFT JOIN $wpdb->term_relationships ON($wpdb->posts.ID = $wpdb->term_relationships.object_id)
    LEFT JOIN $wpdb->term_taxonomy ON($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)
    LEFT JOIN $wpdb->terms ON($wpdb->term_taxonomy.term_id = $wpdb->terms.term_id)
    WHERE $wpdb->posts.post_type = 'post' 
    AND $wpdb->posts.post_status = 'publish'
    AND $wpdb->term_taxonomy.taxonomy = 'technologies'
    AND $wpdb->terms.slug = 'php' OR $wpdb->terms.slug = 'css'
    ORDER BY $wpdb->posts.post_date DESC
    

    More information can be found at the WordPress Codex:
    http://codex.wordpress.org/Displaying_Posts_Using_a_Custom_Select_Query

  2. This is a bit of a delayed reply, but it’s first on Google at the moment for “wordpress related posts by multiple terms” so thought I’d contribute my findings.

    Since this question was posted WordPress has been changed to allow for this type of query. This will give you a list of posts related by any of the custom taxonomy terms assigned to an object:

    $post_cats = wp_get_object_terms(get_the_ID(), 'video_category', array('fields' => 'ids'));
    
    $args=array(
        "tax_query" => array(
            array(
                "taxonomy" => "video_category",
                "field" => "id",
                "terms" => $post_cats
            )
        ),
        'post__not_in' => array(get_the_ID()),
        'post_type' => 'video',
        'posts_per_page' => 8,
        'caller_get_posts' => 1
    );
    
    $related_by_cats = new WP_Query($args);
    

    This is my first contribution to SO, I hope it’s up to standards.

  3. OK, so here is my crack at this. It’s a little hacky, but it works. The big downside is that any other query variables need to be re-added, as when multiple terms are invoked, the fail strips out all of the query vars.

    Also, I did not test this against querying across multiple taxonomies. This only works within a specific taxonomy. Use at your own risk.

    function multi_tax_terms($where) {
        global $wp_query;
        if ( strpos($wp_query->query_vars['term'], ',') !== false && strpos($where, "AND 0") !== false ) {
            // it's failing because taxonomies can't handle multiple terms
            //first, get the terms
            $term_arr = explode(",", $wp_query->query_vars['term']);
            foreach($term_arr as $term_item) {
                $terms[] = get_terms($wp_query->query_vars['taxonomy'], array('slug' => $term_item));
            }
    
            //next, get the id of posts with that term in that tax
            foreach ( $terms as $term ) {
                $term_ids[] = $term[0]->term_id;
            }
    
            $post_ids = get_objects_in_term($term_ids, $wp_query->query_vars['taxonomy']);
    
            if ( !is_wp_error($post_ids) && count($post_ids) ) {
                // build the new query
                $new_where = " AND wp_posts.ID IN (" . implode(', ', $post_ids) . ") ";
                // re-add any other query vars via concatenation on the $new_where string below here
    
                // now, sub out the bad where with the good
                $where = str_replace("AND 0", $new_where, $where);
            } else {
                // give up
            }
        }
        return $where;
    }
    
    add_filter("posts_where", "multi_tax_terms");
    
  4. It’s somehow silly that after implementing custom taxonomies in WP there are no built-in functions to use them at will, and the documentation is close to non-existent. I was looking for a solution, this query solves it (and made my day). Thanks.

    Still, sadly I’m too dumb (OOP blind) to make it into a function so I don’t repeat it all over.
    I get: **Fatal error**: Call to a member function get_results() on a non-object

    I guess I don’t know how to call $wpdb from within a function.

  5. it should be like this:

            global $wp_query;
            query_posts(
                    array_merge(
                        array('taxonomy' => 'technologies', 'term' => array('sql', 'php')),
                        $wp_query->query
                    )
                );
    

    that works for custom post_types, at least.

  6. Hey, I also faced the same problem once. If you don’t have many multiple values, then you can do it in the following way, rather than writing a raw SQL query:

    $loop = new WP_Query(array('technologies' => 'php','technologies' => 'sql')); 
    

    Then you can loop through the wp_query object created here.
    Though this is a very old post and am sure you have already solved the problem. 🙂

  7.  //equivalent to get_posts
     function brand_get_posts($args=array()){
    global $wpdb;
    $sql = "SELECT p.* ";
    $sql.= " FROM $wpdb->posts p";
    $sql.= " LEFT JOIN $wpdb->term_relationships term_r ON(p.ID = term_r.object_id)";
    $sql.= " LEFT JOIN $wpdb->term_taxonomy term_t ON(term_r.term_taxonomy_id = term_t.term_taxonomy_id)";
    $sql.= " LEFT JOIN $wpdb->terms terms ON(term_t.term_id = terms.term_id)";
    $sql.= " WHERE 1=1 ";
    if(!empty($args['post_type'])){
        $sql.= " AND p.post_type = '".$args['post_type']."'";
    }   
    $sql.= " AND p.post_status = 'publish'";
    
    if(!empty($args['taxonomy'])){
        $sql.= " AND term_t.taxonomy = '".$args['taxonomy']."'";
    }   
    if(!empty($args['terms'])&&is_array($args['terms'])){
        $sql.= " AND terms.slug IN ('".implode(",",$args['terms'])."')";
    }
    $sql.= " ORDER BY p.post_date DESC";
    if(!empty($args['posts_per_page'])){
        $sql.=" LIMIT ".$args['posts_per_page'];
    }
    if(!empty($args['offset'])){
        $sql.=" OFFSET ".$args['offset'];
    }
    //echo '<h1>'.$sql.'</h1>';
    return $wpdb->get_results($sql);
     }