Tassonomia Personalizzata e Tax_Query

5 feb 2013, 17:10:37
Visualizzazioni: 31.1K
Voti: 7

Ho avuto molti problemi nell'eseguire una WP_Query con una tax_query sulla mia tassonomia personalizzata.

Sono sicuro al 99.9% che il mio register_taxonomy sia corretto, dato che riesco ad assegnare i termini ai post, vederli nel database e il termine corretto viene restituito con questa funzione: http://pastebin.com/18Aj1ysT.

Ma quando uso una tax_query nella mia WP_Query, non ottengo nessun post. La mia 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 );

Funziona perfettamente senza 'tax_query'. Se uso qualcosa come 'talktype' => 'sunday-talk' invece, usando query_var quando registro la tassonomia, semplicemente ignora la riga come se non ci fosse e stampa qualsiasi talk (invece di dire "nessun post").

Inserendo <?php echo $GLOBALS['nextSundayTalkQuery']->request; ?> ottengo questo:

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

Usando un codice identico per interrogare la tassonomia "category" predefinita di WordPress funziona bene, quindi sembra essere correlato alla mia tassonomia personalizzata o al tipo di post. Per risparmiare spazio in questo post, il mio codice del tipo di post personalizzato è qui:

http://pastebin.com/LxKt2pv5

e il mio codice della tassonomia personalizzata è qui:

http://pastebin.com/NxuuxKuG

Ho provato a includere 'include_children' => false come è stato suggerito, ma senza successo.

Apprezzerei qualsiasi aiuto, poiché questo problema è rimasto irrisolto per mesi con molte persone che hanno provato (e purtroppo fallito) a capire quale fosse il problema.

2
Commenti

Lo 0=1 probabilmente significa che non ha trovato nulla corrispondente alla tua tassonomia e ai termini. Controlla l'ortografia della tassonomia nel database.

Otto Otto
6 feb 2013 04:19:30

Grazie Otto. Per quanto mi piacerebbe che fosse un semplice errore come questo, ho controllato più volte la tassonomia e i termini. Sono ancora perplesso. Tutto sembra a posto nel database - come ho detto, non funziona nemmeno quando uso gli ID invece degli slug.

Pete Gale Pete Gale
6 feb 2013 12:57:51
Tutte le risposte alla domanda 1
11

Innanzitutto, esegui register_post_type su init e register_taxonomy su after_setup_theme che viene chiamato dopo init. Ciò significa che la tua tassonomia personalizzata non sarà disponibile durante la registrazione del post type. Ti suggerirei di rimuovere la parola chiave taxonomies dall'array di argomenti di register_post_type, e registrare manualmente la tassonomia successivamente. Nel tuo codice di esempio sembra che tu stia creando il collegamento post type-tassonomia due volte.

Inoltre, non sono sicuro riguardo a 'query_var' => true, nell'array di argomenti di register_taxonomy. La documentazione dice che puoi impostarlo su false, o una stringa, ma non specifica cosa accadrà se lo imposti su true. Si spera che WordPress sia abbastanza intelligente da sostituirlo con qualcosa di più utile, ma visto che non lo stai impostando esplicitamente su qualcosa di diverso dal nome della tua tassonomia, rimuovilo per ora (ciò significa che verrà usato talktype invece).

Ho inserito questo in un tema vuoto e sembra funzionare bene (cioè stampa una query SQL che include la meta query). Anche eseguire effettivamente una query funziona bene:

functions.php

// Aggiungi post type "Talk" e "Event"
function nc_custom_post_types() {
    register_post_type( 'talk',
        array(
            'labels' => array(
                'name' => __( 'Talks' ),
                'singular_name' => __( 'Talk' )
            ),
            'public' => true,
            'has_archive' => true,
        )
    );


    // Aggiungi la tassonomia "talktype" al post type "talk"
    register_taxonomy('talktype', 'talk', array(
        'hierarchical' => true,
        // Questo array di opzioni controlla le etichette mostrate nell'interfaccia di amministrazione di WordPress
        'labels' => array(
            'name' => _x( 'Tipi di Talk', 'nome generale della tassonomia' ),
            'singular_name' => _x( 'Tipo di Talk', 'nome singolare della tassonomia' ),
            'search_items' =>  __( 'Cerca Tipi di Talk' ),
            'all_items' => __( 'Tutti i Tipi di Talk' ),
            'parent_item' => __( 'Tipo di Talk Genitore' ),
            'parent_item_colon' => __( 'Tipo di Talk Genitore:' ),
            'edit_item' => __( 'Modifica Tipo di Talk' ),
            'update_item' => __( 'Aggiorna Tipo di Talk' ),
            'add_new_item' => __( 'Aggiungi Nuovo Tipo di Talk' ),
            'new_item_name' => __( 'Nuovo Nome Tipo di Talk' ),
            'menu_name' => __( 'Tipi di Talk' ),
        ),
        // Controlla gli slug usati per questa tassonomia
        'rewrite' => array(
            'slug' => 'talktype',
            'with_front' => false, // Non mostra la base della categoria prima di "/locations/"
            'hierarchical' => true // Permetterà URL come "/locations/boston/cambridge/"
        ),
    ));
}
add_action( 'init', 'nc_custom_post_types' );

/* Per scopi di test
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(); ?>

MODIFICA: Ho provato a eseguire il tuo codice senza modifiche, e funziona comunque. Per quanto posso vedere, la parte 0 = 1 nell'SQL viene generata quando non viene trovata la tassonomia o il termine specificato, il che significa che non può essere creato l'INNER JOIN. Assicurati di avere il termine nel tuo database, e che sia il termine che la tassonomia appaiano nella schermata di modifica del tuo post type.

So che hai controllato e ricontrollato il contenuto dei termini nel tuo database, quindi se questo ancora non risolve il tuo problema prova a isolare ulteriormente il problema. Inizia usando un'installazione pulita di WordPress aggiungendo solo il codice che ho fornito sopra, aggiungendo un post talk e assegnandogli il termine sunday-talk. Funziona bene quando lo provo. Prova anche a eseguire manualmente l'SQL direttamente sul tuo database, se non funziona puoi dire con sicurezza che la relazione post/termine non esiste. La query SQL risultante dovrebbe assomigliare a questa (assicurati di cambiare il valore di wp_term_relationships.term_taxonomy_id però):

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
18 feb 2013 18:42:46
Commenti

Ciao Simon, grazie mille per il tuo aiuto. Le cose stanno migliorando - il var_dump($nextSundayTalkQuery->request); restituisce una query "sana" quando provo il codice strutturato come lo hai impostato tu. Questo inizialmente suggerisce che il modo in cui stavo chiamando le mie funzioni register_post_type e register_taxonomy stava causando un problema. Ora che questo funziona, sembra che ci sia un problema con il mio loop dei post, poiché la pagina ora si blocca a questo punto. if ( $nextSundayTalkQuery->have_posts() ) : while ( $nextSundayTalkQuery->have_posts() ) : $nextSundayTalkQuery->the_post(); è quello che sto usando.

Pete Gale Pete Gale
18 feb 2013 20:55:55

Non sono sicuro di cosa ci sia che non va - non avevo sospettato questo come un problema fino ad ora perché funziona bene senza tax_query coinvolto.

Pete Gale Pete Gale
18 feb 2013 20:59:26

@PeteG Quando dici 'si blocca' intendi che la pagina non viene renderizzata? Puoi impostare http://codex.wordpress.org/WP_DEBUG e incollare il messaggio di errore :)

Tom Tom
18 feb 2013 21:28:00

Grazie :) Ottengo:

`Notice: Undefined variable: nextSundayTalkQuery in index.php on line 13

Fatal error: Call to a member function have_posts() on a non-object in index.php on line 13`

Pete Gale Pete Gale
18 feb 2013 21:37:57

Sono riuscito a eseguire con successo una query con while ($nextSundayTalkQuery->have_posts()) { $nextSundayTalkQuery->the_post(); the_title(); } sostanzialmente sostituendo la linea var_dump nel mio esempio. Mantieni tutto il codice in index.php oppure l'hai diviso in qualche modo? Undefined variable: nextSundayTalkQuery può significare solo una cosa - che $nextSundayTalkQuery non è impostato. Fai var_dump($nextSundayTalkQuery); per vedere cosa contiene. Se hai eseguito $nextSundayTalkQuery = new WP_Query( $nextSundayTalkArgs ); prima dovrebbe essere un oggetto WP_Query.

Simon Simon
18 feb 2013 21:45:01

Funziona nella funzione (se la metto dove c'è il var_dump nel tuo esempio), ma non nel mio index.php per qualche motivo. Le tassonomie / tipi di post / filtri dei post sono in functions.php, e il mio loop è in index.php. Facendo un var_dump nel mio index.php restituisce NULL.

Pete Gale Pete Gale
18 feb 2013 22:04:37

Credo che il mio problema sia che sono ancora molto nuovo a WordPress, quindi probabilmente non sto organizzando correttamente il mio tema. functions.php ha sempre funzionato, quindi ho dato per scontato che WordPress lo chiamasse automaticamente, dato che non viene effettivamente richiamato da nessuna parte nel mio index.php (ma tutto il resto al suo interno sembra funzionare).

Pete Gale Pete Gale
18 feb 2013 22:05:38

functions.php verrà incluso automaticamente, ma forse i tuoi file template non possono accedere a tutto ciò di cui hanno bisogno a causa dell'ambito delle funzioni. Aggiornerò la mia risposta tra un attimo con una soluzione che dovrebbe funzionare.

Simon Simon
18 feb 2013 22:06:50

Ho aggiornato il mio esempio con una funzione chiamata sunday_query_args() che puoi usare come argomento della funzione per query_posts() (o WP_Query se necessario).

Simon Simon
18 feb 2013 22:12:14

Vittoria :) Grazie mille! Ora devo capire a) cosa non funzionava nel layout originale del mio functions.php, e b) cosa fanno effettivamente le tue modifiche :) Sembra che non abbia bisogno di un "argomento della funzione" per le altre mie WP_Query nella stessa pagina, quindi potresti spiegarmi un po' cosa fa/perché ne ho bisogno per favore?

Pete Gale Pete Gale
18 feb 2013 22:35:27

Fantastico! query_posts verrà eseguito automaticamente da WordPress utilizzando le variabili di query dalla stringa di query del server web. Ciò significa che recupererà i 10 post più recenti su index.php e una pagina specifica su page.php. Leggere la documentazione dovrebbe aiutarti a iniziare. Dai anche un'occhiata a WP_Query e get_posts e cerca di capire le loro somiglianze e differenze.

Simon Simon
18 feb 2013 23:51:19
Mostra i restanti 6 commenti