Query WP_Query di Tassonomia Personalizzata per Tutti i Termini di una Tassonomia

6 nov 2010, 00:49:49
Visualizzazioni: 67.1K
Voti: 12

Esiste un modo semplice per interrogare tutti i post che sono etichettati con qualsiasi termine di una particolare tassonomia?

Conosco questa tecnica:

$custom_taxonomy_query = new WP_Query( 
 array(
  'taxonomy_name' => 'term_slug',
 )
);

Ma vorrei poter passare un carattere jolly al posto di term_slug, o magari semplicemente una stringa vuota. Questo mi darebbe tutti i post che sono etichettati da qualsiasi termine in quella tassonomia, non solo da un termine specifico.

Grazie per il vostro aiuto, Dave

0
Tutte le risposte alla domanda 5
2
29

Mi sono trovato in una situazione simile Dave. Questo codice ha funzionato per le mie esigenze. Non è l'opzione più snella al mondo ma fa bene il suo lavoro:

// Ottieni tutti gli ID dei termini in una tassonomia specifica
$taxonomy = 'taxonomy_name';
$taxonomy_terms = get_terms( $taxonomy, array(
    'hide_empty' => 0,
    'fields' => 'ids'
) );

// Usa il nuovo argomento tax_query di WP_Query (disponibile dalla versione 3.1)
$taxonomy_query = new WP_Query( array(
    'tax_query' => array(
        array(
            'taxonomy' => $taxonomy,
            'field' => 'id',
            'terms' => $taxonomy_terms,
        ),
    ),
) );

Spero che questo possa aiutare te o chiunque altro stia affrontando lo stesso problema.

Kevin

5 dic 2011 20:02:26
Commenti

Questo è stato estremamente utile per me. Grazie @kevinlearynet

Tyrun Tyrun
22 ott 2012 23:26:52

Ancora rilevante oggi

user1676224 user1676224
18 ott 2018 18:59:53
1
12

Qualcosa del genere potrebbe funzionare:

$args = array(
    'post_type' => 'post',
    'tax_query' => array(
        array(
            'taxonomy' => 'your_custom_taxonomy', // Sostituisci con la tua tassonomia personalizzata
            'operator' => 'EXISTS' // Seleziona i post che hanno almeno un termine in questa tassonomia
        ),
    ),
);
$query = new WP_Query( $args ); // Esegue la query

In pratica stai chiedendo qualsiasi post assegnato a qualsiasi termine all'interno di your_custom_taxonomy.

29 gen 2016 20:44:00
Commenti

Confermo che funziona.

certainlyakey certainlyakey
3 gen 2021 20:59:02
10

Ciao @Dave Morris:

Hai ragione, WordPress se non hai un termine semplicemente ignorerà la tua tassonomia.

Ci sono tre (3) approcci principali che potresti provare:

  1. Usa una query SQL completa con $wpdb->get_results(),

  2. Ottieni una lista di $post->ID per tutti i post nella tua tassonomia e poi passali usando l'argomento 'post__id', oppure

  3. Annota l'SQL usato da WP_Query con uno degli hook che ti permette di aggiungere un INNER JOIN SQL riferito alle tabelle della tassonomia.

Cerco di evitare SQL completo in WordPress finché non è strettamente necessario o finché non si tratta semplicemente di restituire una lista di ID. E in questo caso eviterei di estrarre una lista di $post-ID da usare con l'argomento 'post__id' perché potrebbe causare problemi di prestazioni e persino di memoria se hai molti post. Quindi ci rimane l'opzione #3.

Ho creato una classe per estendere WP_Query chiamata PostsByTaxonomy che utilizza l'hook 'posts_join'. Puoi vederla qui:

class PostsByTaxonomy extends WP_Query {
  var $posts_by_taxonomy;
  var $taxonomy;
  function __construct($args=array()) {
    add_filter('posts_join',array(&$this,'posts_join'),10,2);
    $this->posts_by_taxonomy = true;
    $this->taxonomy = $args['taxonomy'];
    unset($args['taxonomy']);
    parent::query($args);
  }
  function posts_join($join,$query) {
    if (isset($query->posts_by_taxonomy)) {
      global $wpdb;
      $join .=<<<SQL
INNER JOIN {$wpdb->term_relationships} ON {$wpdb->term_relationships}.object_id={$wpdb->posts}.ID
INNER JOIN {$wpdb->term_taxonomy} ON {$wpdb->term_taxonomy}.term_taxonomy_id={$wpdb->term_relationships}.term_taxonomy_id
  AND {$wpdb->term_taxonomy}.taxonomy='{$this->taxonomy}'
SQL;
    }
    return $join;
  }
}

Chiameresti questa classe come vedi sotto. L'argomento 'taxonomy' è obbligatorio ma puoi passare qualsiasi (tutti?) degli altri parametri che WP_Query si aspetta, come 'posts_per_page':

$query = new PostsByTaxonomy(array(
  'taxonomy' => 'category',
  'posts_per_page' => 25,
));
foreach($query->posts as $post) {
  echo " {$post->post_title}\n";
}

Puoi copiare la classe PostsByTaxonomy nel file functions.php del tuo tema, oppure puoi usarla all'interno di un file .php di un plugin che stai scrivendo.

Se vuoi testarla rapidamente ho pubblicato una versione autonoma del codice su Gist che puoi scaricare e copiare nella root del tuo server web come test.php, modificare per il tuo caso d'uso e poi richiedere dal browser usando un URL come http://example.com/test.php.

AGGIORNAMENTO

Per escludere i Post in Evidenza dai post inclusi nella query, prova questo:

$query = new PostsByTaxonomy(array(
  'taxonomy' => 'category',
  'posts_per_page' => 25,
  'caller_get_posts' => true,
));

Oppure se è importante per te che la classe PostsByTaxonomy non includa mai post in evidenza, potresti inserirlo nel costruttore:

  function __construct($args=array()) {
    add_filter('posts_join',array(&$this,'posts_join'),10,2);
    $this->posts_by_taxonomy = true;
    $this->taxonomy = $args['taxonomy'];
    $args['caller_get_posts'] = true     // No Post in Evidenza
    unset($args['taxonomy']);
    parent::query($args);
  }

AGGIORNAMENTO 2

Dopo aver pubblicato quanto sopra ho scoperto che 'caller_get_posts' sarà deprecato e 'ignore_sticky_posts' sarà utilizzato in WordPress 3.1.

6 nov 2010 09:45:53
Commenti

Mike, grazie per il tuo aiuto. Per qualche motivo non riesco a farlo funzionare. Non restituisce solo i post con i termini assegnati dalla mia tassonomia personalizzata. Sembra sempre restituire altri post. Tuttavia, non restituisce tutti i post, quindi sta sicuramente facendo qualcosa... Posso usare la funzione $query->have_posts() per iterare? Nessuno dei due metodi sembra funzionare per me, in ogni caso.

Dave Morris Dave Morris
6 nov 2010 15:40:15

Ah, questo è interessante. Ho trovato la query nel log mysql che ottiene i due post che mi aspetto, e funziona. Ma per qualche motivo, quando eseguo il loop su $query->posts, tornano cinque post. L'unica altra cosa che noto è che subito dopo l'esecuzione della query dei post della tassonomia personalizzata, viene eseguita un'altra query che recupera altri tre post, tramite i loro post_id. E poi immagino che tutti e cinque i post vengano inseriti in un unico array di risultati.

Dave Morris Dave Morris
6 nov 2010 16:07:54

Credo di aver capito. Questa query personalizzata sembra includere i post sticky, anche se non sono in quella tassonomia personalizzata. Hai qualche idea su come gestire correttamente i post sticky, o almeno su come rimuoverli da questa query particolare? Grazie, Dave

Dave Morris Dave Morris
6 nov 2010 16:14:12

Beh, sono "appiccicosi", giusto? :)

È un comportamento strano, credo, ma se usi caller_get_posts=1 dovrebbero sparire:

http://codex.wordpress.org/Function_Reference/query_posts#Sticky_Post_Parameters

Spero che questo ti aiuti.

MikeSchinkel MikeSchinkel
6 nov 2010 18:54:51

Quel if(isset($query->posts_by_taxonomy)) è un bel trucco per combinare la metodologia object-oriented con l'approccio agli hook di WordPress.

Jan Fabry Jan Fabry
6 nov 2010 20:21:08

@Jan Fabry - Sì, grazie! Mi ci sono voluti solo circa 2 anni di tentativi ed errori prima che mi venisse in mente. Ora ovviamente sembra ovvio... :)

MikeSchinkel MikeSchinkel
7 nov 2010 01:06:20

Ha funzionato! Grazie mille per il tuo aiuto. Mi piace imparare nuovi trucchi su WordPress, specialmente quelli OO.

Dave Morris Dave Morris
7 nov 2010 16:22:30

@Dave Morris - Prego. A proposito, ho appena scoperto che in WP 3.1 si chiamerà 'ignore_sticky_posts'.

MikeSchinkel MikeSchinkel
7 nov 2010 22:50:02

@MikeSchinkel E per quanto riguarda l'impaginazione? Questo funziona bene, ma l'impaginazione per questa query non funziona come dovrebbe nel mio caso... http://wordpress.stackexchange.com/q/57884/12261

Ajay Patel Ajay Patel
9 lug 2012 14:09:16

Questo è un bel trucco e funziona ancora! Ma cosa succede se volessi includere un array di tassonomie? 2 o 3 tassonomie, cosa dovremmo modificare nella query?

Rounds Rounds
30 ott 2015 00:06:33
Mostra i restanti 5 commenti
6

Dovresti semplicemente poter impostare la tassonomia e negare per includere un termine..

Es.

<?php
$your_query = new WP_query;
$your_query->query( array( 'taxonomy' => 'nome-della-tua-tassonomia' ) );
?>

Che sarebbe praticamente lo stesso della query eseguita da un archivio tassonomico.

6 nov 2010 01:33:32
Commenti

Non funziona.

Dave Morris Dave Morris
6 nov 2010 01:43:21

La linea 1432 di query.php verifica se taxonomy OPPURE term sono vuoti, quindi non puoi semplicemente non passare uno slug... Qualche altra idea?

Dave Morris Dave Morris
6 nov 2010 01:50:04

@t31os - Anche la mia prima reazione è stata quella; in realtà ci sono caduto più di una volta perché continuo a dimenticarlo. Ma @Dave Morris ha ragione; se non è una coppia taxonomy/term allora WP_Query semplicemente la scarta.

MikeSchinkel MikeSchinkel
6 nov 2010 09:47:17

Wow, non lo sapevo, è un po' sciocco in realtà... lezione imparata... :) Mi aspettavo che funzionasse come i parametri meta_key / meta_value (non so perché)...

t31os t31os
6 nov 2010 10:24:58

@t31os - Esatto, purtroppo WP_Query non è implementato in modo così elegante. Sono quasi 1200 righe di casi speciali hard-coded.

MikeSchinkel MikeSchinkel
6 nov 2010 19:06:30

"quasi 1200 righe di casi speciali hard-coded." ... questa mi ha fatto ridere, ho dovuto +1 il commento... ;)

t31os t31os
6 nov 2010 19:19:19
Mostra i restanti 1 commenti
0

In retrospettiva, ho creato un mix tra i suggerimenti di MikeSchinkel e t31os. È possibile inserirlo nelle query esistenti al volo, ma richiede WordPress 3.1:

Plugin per ottenere un Feed RSS per articoli contenenti qualsiasi termine da una tassonomia.

5 feb 2011 18:06:56