web-dev-qa-db-ja.com

カスタム分類法とTax_Query

カスタム分類法でWP_Querytax_queryを実行するのに苦労しています。

私は99.9%が私のregister_taxonomyが正しいと確信しています。正しいキーワードで投稿にタグを付け、データベースでそれを見ることができ、そして正しい用語がこの関数で返されるからです。 http://Pastebin.com/18Aj1ysT

しかし、tax_queryWP_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'がなくても完全に機能します。分類法を登録するときにquery_varを使用して代わりに 'talktype' => 'sunday-talk'のようなものを使用した場合、存在しないと考えられている行を無視し、(「投稿なし」と言う代わりに)トークを出力します。 。

<?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のデフォルトの「カテゴリ」分類法を照会すると問題なく動作するので、カスタム分類法または投稿タイプに関連しているようです。この投稿のスペースを節約するために、私のカスタム投稿タイプコードは次のとおりです。

http://Pastebin.com/LxKt2pv5

そして私のカスタム分類コードはここにあります:

http://Pastebin.com/NxuuxKuG

提案されているように'include_children' => falseを含めることを試みましたが、運が悪いです。

この問題は何ヶ月もの間解決できないもので、何が問題なのかを解明しようとしている(そして残念ながら失敗している)ので、私はあらゆる助けをいただければ幸いです。

6
Pete Gale

まず最初に、initに対してregister_post_typeを、initの後に呼び出されるregister_taxonomyに対してafter_setup_themeを実行します。これは、投稿タイプを登録するときにカスタム分類法が利用できなくなることを意味します。 register_post_type引数配列からtaxonomiesキーワードを削除し、後で分類法を手動で登録することをお勧めします。サンプルコードでは、ポストタイプ分類のリンクを2回作成しているように見えます。

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

_ edit _ :コードを変更せずに実行してみてください。実際にも同様に機能します。私の知る限りでは、SQLの0 = 1ビットは、指定された分類法または用語が見つからないときに生成されます。つまり、INNER JOINは作成できません。データベースに用語があること、および用語と分類法の両方が投稿タイプの編集画面に表示されることを確認してください。

私はあなたがあなたのデータベースの用語の内容をチェックし、二重チェックしたことを知っています、それでなおもこれがあなたの問題を解決しないなら問題をさらに分離することを試みなさい。上で提供したコードだけを追加し、talkという投稿を追加し、それにsunday-talkという用語を割り当てる、きれいなWordPressインストールを使用することから始めます。試してみるとうまくいきます。また、データベース上で直接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
7
Simon