Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I've been having a lot of trouble getting a WP_Query running with a tax_query on my custom taxonomy.

I'm 99.9% sure that my register_taxonomy is correct, as I'm able to tag posts with the right term, see it in the database, and the correct term returns with this function: http://pastebin.com/18Aj1ysT .

But when I use a tax_query in my WP_Query, I get no posts. My query is:

$nextSundayTalkArgs = array(  
    'post_type' => 'talk',  
    'posts_per_page' => 1,  
    'tax_query' => array(  
        array(  
            'taxonomy' => 'talktype',  
            'field' => 'slug',  
            'terms' => 'sunday-talk'  
        )  
    )  
);  
$nextSundayTalkQuery = new WP_Query( $nextSundayTalkArgs );

It works perfectly without 'tax_query'. If I use something like 'talktype' => 'sunday-talk' instead, using query_var when I register the taxonomy, it simply ignores the line as thought it weren't there and prints any talk (instead of saying "no posts").

Inserting <?php echo $GLOBALS['nextSundayTalkQuery']->request; ?> gets me this:

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID 
FROM wp_posts WHERE 1=1
AND 0 = 1 
AND wp_posts.post_type = 'talk' 
AND (
    wp_posts.post_status = 'publish' 
    OR wp_posts.post_author = 1 
    AND wp_posts.post_status = 'private'
) 
GROUP BY wp_posts.ID 
ORDER BY wp_posts.post_date DESC 
LIMIT 0, 1

Using identical code to query WordPress' default "category" taxonomy works fine, so it seems to be related to my custom taxonomy or post type. To save space on this post, my custom post type code is here:

http://pastebin.com/LxKt2pv5

and my custom taxonomy code is here:

http://pastebin.com/NxuuxKuG

I've tried including 'include_children' => false as has been suggested, but no luck.

I would appreciate any and all help, as this problem has been unsolvable for months with many people trying (and failing, unfortunately) to figure out what's wrong.

share|improve this question
    
The 0=1 likely means it found nothing matching your taxonomy and terms. Check the spelling of the taxonomy in the db. –  Otto Feb 6 '13 at 2:19
    
Thanks Otto. As much as I'd love it to be a simple mistake like this, I've been back and forth checking the taxonomy and terms several times. Still at a loss. Everything seems fine in the database - like I mentioned, it doesn't even work when I use IDs instead of slugs. –  Pete Gale Feb 6 '13 at 10:57

1 Answer 1

up vote 5 down vote accepted
+150

First of all, you run register_post_type on init and register_taxonomy on after_setup_theme which is called after init. This means your custom taxonomy will not be available when registering the post type. I would suggest you remove the taxonomies keyword from the register_post_type arguments array, and just register the taxonomy manually at afterwards. I n your example code it looks like you are creating the post type-taxonomy link twice.

I am also not sure about 'query_var' => true, in the register_taxonomy arguments array. The documentation says you can set it to false, or a string, but does not state what will happen if you set it to true. Hopefully WordPress will be smart enough to substitute it with something more useful, but since you are not explicitly setting it to something other than your taxonomy name just remove it for now (that means talktype will be used instead).

I just put this in an empty theme and it appears to be working fine (i.e. it prints a SQL query including the meta query). Actually running a query instead works fine too:

functions.php

// Add post types of "Talk" and "Event"
function nc_custom_post_types() {
    register_post_type( 'talk',
        array(
            'labels' => array(
                'name' => __( 'Talks' ),
                'singular_name' => __( 'Talk' )
            ),
            'public' => true,
            'has_archive' => true,
        )
    );


    // Add new "talktype" taxonomy to "talk" post type
    register_taxonomy('talktype', 'talk', array(
        'hierarchical' => true,
        // This array of options controls the labels displayed in the WordPress Admin UI
        'labels' => array(
            'name' => _x( 'Talk Types', 'taxonomy general name' ),
            'singular_name' => _x( 'Talk Type', 'taxonomy singular name' ),
            'search_items' =>  __( 'Search Talk Types' ),
            'all_items' => __( 'All Talk Types' ),
            'parent_item' => __( 'Parent Talk Type' ),
            'parent_item_colon' => __( 'Parent Talk Type:' ),
            'edit_item' => __( 'Edit Talk Type' ),
            'update_item' => __( 'Update Talk Type' ),
            'add_new_item' => __( 'Add New Talk Type' ),
            'new_item_name' => __( 'New Talk Type Name' ),
            'menu_name' => __( 'Talk Types' ),
        ),
        // Control the slugs used for this taxonomy
        'rewrite' => array(
            'slug' => 'talktype',
            'with_front' => false, // Don't display the category base before "/locations/"
            'hierarchical' => true // This will allow URL's like "/locations/boston/cambridge/"
        ),
    ));
}
add_action( 'init', 'nc_custom_post_types' );

/* For testing purposes
add_action('wp', 'test');
function test() {

    $nextSundayTalkArgs = array(
        'post_type' => 'talk',
        'posts_per_page' => 1,
        'tax_query' => array(
            array(
                'taxonomy' => 'talktype',
                'field' => 'slug',
                'terms' => 'sunday-talk'
            )
        )
    );
    $nextSundayTalkQuery = new WP_Query( $nextSundayTalkArgs );

    var_dump($nextSundayTalkQuery->request);
    die();
}
*/

function sunday_query_args() {

    $nextSundayTalkArgs = array(
        'post_type' => 'talk',
        'posts_per_page' => 1,
        'tax_query' => array(
            array(
                'taxonomy' => 'talktype',
                'field' => 'slug',
                'terms' => 'sunday-talk'
            )
        )
    );

    return $nextSundayTalkArgs;
}

index.php

<?php get_header(); ?>
<?php query_posts(sunday_query_args()); ?>
<div id="content">
    <?php while ( have_posts() ) : the_post(); ?>    
         <article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
            <h1 class="entry-title"><?php the_title(); ?></h1>
            <div class="entry-content">
                <?php the_content(); ?>
            </div>
        </article>
    <?php endwhile; ?>
</div>
<?php get_sidebar(); ?>
<?php get_footer(); ?>

EDIT: Just tried running your code unmodified, and that actually works as well. As far as I can tell, the 0 = 1 bit in the SQL is generated when either the taxonomy or term specified is not found, which means the INNER JOIN can not be created. Make sure you have the term in your database, and that both term and taxonomy shows up in the edit screen of your post type.

I know you have checked and double-checked the term contents of your database, so if this still does not solve your issue try to isolate the problem further. Start by using a clean WordPress installation adding only the code I supplied above, adding a talk post and assigning it the sunday-talk term. That works fine when I try it. Also try, manually running the SQL directly on you database, if that does not work you it's safe to say that the post/term relation does not exist. The resulting SQL query should look something like this (be sure change the value of wp_term_relationships.term_taxonomy_id though):

SELECT SQL_CALC_FOUND_ROWS  wp_posts.ID FROM wp_posts  INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) WHERE 1=1  AND ( wp_term_relationships.term_taxonomy_id IN (4) ) AND wp_posts.post_type = 'talk' AND (wp_posts.post_status = 'publish') GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 1
share|improve this answer
    
Hi Simon, thanks so much for your help. Things are looking up - the var_dump($nextSundayTalkQuery->request); is returning a "healthy" query when I try the code laid out like you have it. That first suggests that the way I was calling my register_post_type and register_taxonomy functions was causing a problem. Now that's working, it looks as though there's an issue with my posts loop, as the page is now crashing at this point. if ( $nextSundayTalkQuery->have_posts() ) : while ( $nextSundayTalkQuery->have_posts() ) : $nextSundayTalkQuery->the_post(); is what I'm using. –  Pete Gale Feb 18 '13 at 18:55
    
Not sure what's wrong with it - hadn't suspected this as a problem until now because it works OK without tax_query involved. –  Pete Gale Feb 18 '13 at 18:59
    
@PeteG When you say 'crashing' do you mean the page does not render? can you set codex.wordpress.org/WP_DEBUG and paste the error message :) –  Tom Feb 18 '13 at 19:28
    
Thanks :) I get: Notice: Undefined variable: nextSundayTalkQuery in index.php on line 13 Fatal error: Call to a member function have_posts() on a non-object in index.php on line 13 –  Pete Gale Feb 18 '13 at 19:37
1  
Victory :) Thank you so much! Now I need to figure out a) what about my original functions.php layout wasn't working, and b) what your changes actually do :) I don't seem to need a "function argument" for my other WP_Querys on the same page, so could you explain a little about what it does / why I need it please? –  Pete Gale Feb 18 '13 at 20:35

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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