[wp-trac] [WordPress Trac] #12891: Advanced multi-taxonomy WP_Query()s

WordPress Trac wp-trac at lists.automattic.com
Wed Apr 7 12:04:25 UTC 2010


#12891: Advanced multi-taxonomy WP_Query()s
-----------------------------+----------------------------------------------
 Reporter:  markjaquith      |       Owner:  ryan               
     Type:  feature request  |      Status:  new                
 Priority:  normal           |   Milestone:  3.1                
Component:  Query            |     Version:  3.0                
 Severity:  normal           |    Keywords:  taxonomies,WP_Query
-----------------------------+----------------------------------------------
 We have this great taxonomy system, but we're only able to query one of
 them at a time. There is no way to ask for posts that are in the 'cars'
 category but lack the "VW Beetle" tag. What people end up doing is
 crafting complex category systems to simulate multiple taxonomies. That's
 lame. We should make them want to use multiple taxonomies. Let's give them
 the tools to do it.

 Proposed syntax, and half-working example implementation:

 {{{
 <?php

 class WP_Query_Tax_Or {
         var $contents = array();
         function WP_Query_Tax_Or( $array ) {
                 $this->contents = $array;
                 return $this;
         }
 }

 class WP_Query_Tax_And {
         var $contents = array();
         function WP_Query_Tax_And( $array ) {
                 $this->contents = $array;
                 return $this;
         }
 }

 class WP_Query_Tax {
         var $taxonomy;
         var $object;
         var $ID;
         function WP_Query_Tax( $taxonomy, $object ) {
                 $this->taxonomy = $taxonomy;
                 $this->object = $object;
                 $this->ID =
 wp_some_function_to_get_an_ID_from_ID_or_name_or_slug( $taxonomy, $object
 );
                 return $this;
         }
 }

 class WP_Query_Tax_Not {
         var $taxonomy;
         var $object;
         var $ID;
         function WP_Query_Tax_Not( $taxonomy, $object ) {
                 $this->taxonomy = $taxonomy;
                 $this->object = $object;
                 $this->ID =
 wp_some_function_to_get_an_ID_from_ID_or_name_or_slug( $taxonomy, $object
 );
                 return $this;
         }
 }


 function wp_tax_and() {
         return new WP_Query_Tax_And( func_get_args() );
 }

 function wp_tax_or() {
         return new WP_Query_Tax_Or( func_get_args() );
 }

 function wp_tax( $taxonomy, $object ) {
         return new WP_Query_Tax( $taxonomy, $object );
 }

 function wp_tax_not( $taxonomy, $object ) {
         return new WP_Query_Tax_Not( $taxonomy, $object );
 }

 function wp_some_function_to_get_an_ID_from_ID_or_name_or_slug( $taxonomy,
 $object ) {
         return $object;
 }

 $array = array(
         'tax' => wp_tax_and(
                 wp_tax_or(
                         wp_tax( 'post_category', 59 ),
                         wp_tax( 'post_tag', 'web' )
                 ),
                 wp_tax_not( 'post_category', 24 ),
                 wp_tax_not( 'post_tag', 'wordpress' )
         )
 );

 var_dump( $array );
 }}}

 Simple enough. group with {{{wp_tax_and()}}} or {{{wp_tax_or()}}}. Select
 a taxonomy item using {{{wp_tax( 'taxonomy', 'ID or name or slug' )}}} and
 omit a taxonomy item using {{{wp_tax_not( 'taxonomy', 'ID or name or slug'
 )}}}.

 If you run the example code, you'll get an array of objects that could be
 iterated by WP_Query code using subqueries and parenthesis to generate the
 precise query that was requested.

 It'll translate directly into SQL. Start of AND or OR means you start
 parenthesis, and join all children elements with AND or OR as appropriate.
 Getting to the end of an AND or OR means you close parenthesis. And then
 just use IN() and NOT IN() for {{{wp_tax()}}} and {{{wp_tax_not()}}}
 respectively.

-- 
Ticket URL: <http://core.trac.wordpress.org/ticket/12891>
WordPress Trac <http://core.trac.wordpress.org/>
WordPress blogging software


More information about the wp-trac mailing list