Custom Taxonomy and Tax_Query

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 .

Read More

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.

Related posts

Leave a Reply

1 comment

  1. 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 afterwards. In 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