问题描述

使用 tax_query 在我的自定义分类法中运行一个 WP_Query,我遇到了很多麻烦。

我已经 99.9%肯定我的 register_taxonomy 是正确的,因为我可以使用正确的术语来标记帖子,在数据库中查看它,并且使用此功能返回正确的术语:http://pastebin.com/18Aj1ysT

但是当我在 WP_Query 中使用 tax_query 时,我没有发表任何帖子。我的查询是:

$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 );

它没有’tax_query’ 完美无缺。如果我使用像’talktype’ => ‘sunday-talk’ 改为使用 query_var,当我注册分类时,它只是忽略该行,以为它不在那里打印任何谈话 (而不是说”no posts”) 。

插入<?php echo $GLOBALS['nextSundayTalkQuery']->request; ?> 得到我:

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

使用相同的代码查询 WordPress 的默认”category” 分类工作正常,所以它似乎与我的自定义分类法或帖子类型有关。为了节省这篇文章的空间,我的自定义帖子类型代码在这里:

http://pastebin.com/LxKt2pv5

我的定制分类代码在这里:

http://pastebin.com/NxuuxKuG

我已经尝试过包括'include_children' => false 已经建议,但没有运气。

我会感谢所有的帮助,因为这个问题在许多人尝试 (不幸的是) 失败了几个月才解决了什么是错误的。

最佳解决方案

首先,您在 initregister_taxonomy 上运行 register_post_typeafter_setup_themeinit 之后调用。这意味着在注册帖子类型时,您的自定义分类法将不可用。我建议您从 register_post_type 参数数组中删除 taxonomies 关键字,然后手动注册分类法。在您的示例代码中,您似乎正在创建两次 Post type-taxonomy 。

我也不确定'query_var' => true,register_taxonomy 参数数组中。该文档说您可以将其设置为 false 或字符串,但不会声明如果将其设置为 true 将会发生什么。希望 WordPress 会很聪明,可以用更有用的东西替代它,但是由于你没有明确地将它设置为除你的分类名称之外的东西,只是删除它现在 (这意味着 talktype 将被替代使用) 。

我只是把它放在一个空的主题,它似乎工作正常 (即打印一个 SQL 查询,包括元查询) 。实际运行查询也可以正常工作:

的 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(); ?>

编辑:只是尝试运行你的代码未经修改,实际上也是如此。据我所知,SQL 中的 0 = 1 位未指定分类或术语时生成,这意味着无法创建 INNER JOIN 。确保您的数据库中有该术语,并且术语和分类都显示在您的帖子类型的编辑屏幕中。

我知道你已经检查过和 double-checked 数据库的术语内容,所以如果这还是不能解决你的问题,试图进一步隔离问题。首先使用一个干净的 WordPress 安装,只添加上面提供的代码,添加一个 talk 文件并将其分配给 sunday-talk 术语。当我尝试它的工作正常。还要尝试,直接在您的数据库上运行 SQL,如果这不工作,您可以安全地说,post /term 关系不存在。生成的 SQL 查询应该是这样的 (请确保改变 wp_term_relationships.term_taxonomy_id 的值):

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

参考文献

注:本文内容整合自 Google/Baidu/Bing 辅助翻译的英文资料结果。如果您对结果不满意,可以加入我们改善翻译效果:薇晓朵技术论坛。