問題描述

使用 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 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。