web-dev-qa-db-fra.com

Taxonomie personnalisée et Tax_Query

J'ai eu beaucoup de difficulté à obtenir un WP_Query avec un tax_query sur ma taxonomie personnalisée.

Je suis sûr à 99,9% que mon register_taxonomy est correct, car je peux baliser les posts avec le bon terme, le voir dans la base de données, et le terme correct revient avec cette fonction: http://Pastebin.com/ 18Aj1ysT .

Mais lorsque j'utilise un tax_query dans mon WP_Query, je ne reçois aucun message. Ma requête est:

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

Cela fonctionne parfaitement sans 'tax_query'. Si j'utilise quelque chose comme 'talktype' => 'sunday-talk', en utilisant query_var lorsque j'enregistre la taxonomie, il ignore simplement la ligne comme si elle n'existait pas et affiche une discussion (au lieu de "no posts") .

Insérer <?php echo $GLOBALS['nextSundayTalkQuery']->request; ?> me donne ceci:

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

L'utilisation d'un code identique pour interroger la taxonomie par défaut de la "catégorie" de WordPress fonctionne correctement. Elle semble donc être liée à ma taxonomie personnalisée ou à mon type de publication. Pour économiser de l'espace sur ce post, mon code de type de post personnalisé est ici:

http://Pastebin.com/LxKt2pv5

et mon code de taxonomie personnalisé est ici:

http://Pastebin.com/NxuuxKuG

J'ai essayé d'inclure 'include_children' => false comme cela a été suggéré, mais pas de chance.

J'apprécierais toute aide, car ce problème est insoluble depuis des mois et de nombreuses personnes tentent (et échouent malheureusement) de comprendre ce qui ne va pas.

6
Pete Gale

Tout d’abord, vous exécutez register_post_type sur init et register_taxonomy sur after_setup_theme qui est appelé après init. Cela signifie que votre taxonomie personnalisée ne sera pas disponible lors de l'enregistrement du type de publication. Je vous suggérerais de supprimer le mot clé taxonomies du tableau d'arguments register_post_type et d'inscrire simplement la taxonomie manuellement par la suite. Dans votre exemple de code, il semble que vous créiez deux fois le lien post-type-taxonomie.

Je ne suis pas sûr non plus de 'query_var' => true, dans le tableau d'arguments register_taxonomy. La documentation indique que vous pouvez le définir sur false ou sur une chaîne, mais n'indique pas ce qui se passera si vous le définissez sur true. Espérons que WordPress sera assez intelligent pour le remplacer par quelque chose de plus utile, mais puisque vous ne le définissez pas explicitement à autre chose que votre nom de taxonomie, supprimez-le pour l'instant (cela signifie que talktype sera utilisé à la place).

Je viens de mettre cela dans un thème vide et il semble fonctionner correctement (c'est-à-dire qu'il imprime une requête SQL, y compris la méta requête). Effectuer une requête à la place fonctionne également très bien:

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: Vous venez d’essayer d’exécuter votre code sans modification, et cela fonctionne aussi. Autant que je sache, le bit 0 = 1 du code SQL est généré lorsque la taxonomie ou le terme spécifié n'est pas trouvé, ce qui signifie que le INNER JOIN ne peut pas être créé. Assurez-vous que le terme est dans votre base de données et que le terme et la taxonomie apparaissent dans l'écran de modification de votre type de publication.

Je sais que vous avez vérifié et revérifié le contenu des termes de votre base de données. Par conséquent, si cela ne résout toujours pas le problème, essayez d’isoler davantage le problème. Commencez par utiliser une nouvelle installation WordPress en ajoutant uniquement le code que j'ai fourni ci-dessus, en ajoutant une publication talk et en lui affectant le terme sunday-talk. Cela fonctionne bien quand je l'essaie. Essayez également d’exécuter manuellement le code SQL directement sur votre base de données. Si cela ne fonctionne pas, vous pouvez affirmer que la relation poste/terme n’existe pas. La requête SQL résultante devrait ressembler à ceci (assurez-vous de changer la valeur de wp_term_relationships.term_taxonomy_id si):

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