Interogare WP_Query pentru taxonomie personalizată cu toate termenii dintr-o taxonomie?

6 nov. 2010, 00:49:49
Vizualizări: 67.1K
Voturi: 12

Există o modalitate simplă de a interoga toate articolele care sunt etichetate cu orice termen dintr-o taxonomie specifică?

Cunosc această tehnică:

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

Dar aș dori să pot folosi fie un wildcard în locul term_slug, fie poate doar un șir gol. Astfel aș putea obține toate articolele care sunt etichetate cu orice termen din acea taxonomie, nu doar cu un termen specific.

Mulțumesc pentru ajutor, Dave

0
Toate răspunsurile la întrebare 5
2
29

Am întâlnit o situație similară, Dave. Acest cod a funcționat pentru nevoile mele. Nu este cea mai elegantă soluție, dar își face treaba:

// Obține toate ID-urile de termeni dintr-o taxonomie dată
$taxonomy = 'nume_taxonomie';
$taxonomy_terms = get_terms( $taxonomy, array(
    'hide_empty' => 0,
    'fields' => 'ids'
) );

// Folosește noul argument tax_query pentru WP_Query (disponibil din versiunea 3.1)
$taxonomy_query = new WP_Query( array(
    'tax_query' => array(
        array(
            'taxonomy' => $taxonomy,
            'field' => 'id',
            'terms' => $taxonomy_terms,
        ),
    ),
) );

Sper că acest lucru te va ajuta pe tine sau pe alții care întâmpină aceeași problemă.

Kevin

5 dec. 2011 20:02:26
Comentarii

Acest lucru a fost extrem de util pentru mine. Mulțumesc @kevinlearynet

Tyrun Tyrun
22 oct. 2012 23:26:52

Încă relevant și în zilele noastre

user1676224 user1676224
18 oct. 2018 18:59:53
1
12

Ceva de genul acesta ar putea funcționa:

$args = array(
    'post_type' => 'post',
    'tax_query' => array(
        array(
            'taxonomy' => 'your_custom_taxonomy',
            'operator' => 'EXISTS'
        ),
    ),
);
$query = new WP_Query( $args );

În esență, ceri orice articol atribuit oricărui termen din your_custom_taxonomy.

29 ian. 2016 20:44:00
Comentarii

Confirm că funcționează.

certainlyakey certainlyakey
3 ian. 2021 20:59:02
10

Salut @Dave Morris:

Ai dreptate, WordPress decide că dacă nu ai un termen, pur și simplu va ignora taxonomia ta.

Există trei (3) abordări principale pe care le poți încerca:

  1. Folosește o interogare SQL completă cu $wpdb->get_results(),

  2. Obține o listă de $post->IDs pentru toate articolele din taxonomia ta și apoi trece-le folosind argumentul 'post__id', sau

  3. Adnotează SQL-ul folosit de WP_Query cu unul dintre hook-urile care îți permit să adaugi un INNER JOIN SQL referindu-te la tabelele de taxonomie.

Încerc să evit SQL-ul complet în WordPress până când nu se poate altfel sau până când returnează doar o listă de ID-uri. Și în acest caz, aș evita să extrag o listă de $post-IDs pentru a le folosi cu argumentul 'post__id' pentru că ar putea întâmpina probleme de performanță și chiar probleme de memorie dacă ai multe articole. Așa că ne rămâne varianta #3.

Am creat o clasă pentru a extinde WP_Query numită PostsByTaxonomy care folosește hook-ul 'posts_join'. O poți vedea aici:

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;
  }
}

Ai putea apela această clasă așa cum vezi mai jos. Argumentul 'taxonomy' este obligatoriu dar poți pasa oricare (toate?) dintre ceilalți parametri pe care WP_Query îi așteaptă, cum ar fi 'posts_per_page':

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

Poți copia clasa PostsByTaxonomy în fișierul functions.php al temei tale, sau o poți folosi într-un fișier .php al unui plugin pe care îl scrii.

Dacă vrei să o testezi rapid, am postat o versiune independentă a codului pe Gist pe care o poți descărca și copia în root-ul serverului tău web ca test.php, modifică pentru cazul tău de utilizare, și apoi solicit-o din browser folosind un URL precum http://example.com/test.php.

ACTUALIZARE

Pentru a exclude Articolele Lipicioase din articolele incluse în interogare, încearcă asta:

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

Sau dacă este important pentru tine ca clasa PostsByTaxonomy să nu includă niciodată articole lipicioase, ai putea pune asta în constructor:

  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     // Fără Articole Lipicioase
    unset($args['taxonomy']);
    parent::query($args);
  }

ACTUALIZARE 2

După ce am postat cele de mai sus, am aflat că 'caller_get_posts' va fi depreciat și 'ignore_sticky_posts' va fi folosit în WordPress 3.1.

6 nov. 2010 09:45:53
Comentarii

Mike, Mulțumesc pentru ajutor. Din anumite motive, nu reușesc să fac asta să funcționeze. Nu returnează doar postările care au termeni atribuiți din taxonomia mea personalizată. Pare să returneze întotdeauna și alte postări. Cu toate acestea, nu returnează toate postările, deci cu siguranță face ceva... Pot folosi funcția $query->have_posts() pentru a itera? Niciuna dintre metode nu pare să funcționeze pentru mine, în niciun caz.

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

Ah, asta este interesant. Am găsit în jurnalul mysql interogarea care obține cele două postări pe care le aștept și funcționează. Dar, din anumite motive, când parcurg $query->posts, se întorc cinci postări. Singurul alt lucru pe care îl observ este că imediat după ce rulează interogarea pentru postările din taxonomia personalizată, rulează o altă interogare care preia încă trei postări, după post_id. Și apoi cred că toate cele cinci postări sunt puse într-un singur array de rezultate.

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

Cred că am înțeles. Această interogare personalizată pare să includă postări lipicioase (sticky posts), chiar dacă acestea nu sunt în acea taxonomie personalizată. Ai idei despre cum să respectăm corect postările lipicioase sau măcar cum să le eliminăm din această interogare specifică? Mulțumesc, Dave

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

Ei sunt "lipicioși", nu-i așa? :)

E un comportament ciudat, cred, dar dacă folosești caller_get_posts=1 ar trebui să dispară:

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

Sper că te ajută.

MikeSchinkel MikeSchinkel
6 nov. 2010 18:54:51

Acel if(isset($query->posts_by_taxonomy)) este un truc drăguț pentru a combina metodologia orientată pe obiecte cu metodologia de hook-uri din WordPress.

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

@Jan Fabry - Da, mulțumesc! Mi-a luat cam 2 ani de încercări și erori până să-mi vină ideea. Bineînțeles acum pare evident... :)

MikeSchinkel MikeSchinkel
7 nov. 2010 01:06:20

A funcționat! Mulțumesc mult pentru ajutor. Îmi place să învăț trucuri noi în WordPress, mai ales cele orientate pe obiect.

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

@Dave Morris - Cu plăcere. Apropo, tocmai am aflat că în WP 3.1 se va numi 'ignore_sticky_posts'.

MikeSchinkel MikeSchinkel
7 nov. 2010 22:50:02

@MikeSchinkel Dar ce zici de paginare, asta funcționează bine dar paginarea pentru această interogare nu merge cum ar trebui în cazul meu... http://wordpress.stackexchange.com/q/57884/12261

Ajay Patel Ajay Patel
9 iul. 2012 14:09:16

Acesta este un truc frumos și încă funcționează! Dar dacă aș dori să includ o serie de taxonomii? 2 sau 3 taxonomii, ce ar trebui să modificăm în interogare?

Rounds Rounds
30 oct. 2015 00:06:33
Arată celelalte 5 comentarii
6

Ar trebui să poți seta taxonomia și să excludeți un termen..

De exemplu:

<?php
$your_query = new WP_query;
$your_query->query( array( 'taxonomy' => 'numele-taxonomiei-tale' ) );
?>

Ceea ce ar fi practic același lucru ca interogarea pe care o execută o arhivă de taxonomie.

6 nov. 2010 01:33:32
Comentarii

Nu funcționează.

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

Linia 1432 din query.php verifică dacă taxonomia SAU termenul sunt goale, deci nu poți să nu transmiți un slug... Alte idei?

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

@t31os - A fost și prima mea reacție; de fapt, am dat peste asta de mai multe ori pentru că tot uit. Dar @Dave Morris are dreptate; dacă nu este o pereche taxonomie/termen, atunci WP_Query pur și simplu o ignoră.

MikeSchinkel MikeSchinkel
6 nov. 2010 09:47:17

Wow, nu știam asta, e cam aiurea... lecție învățată... :) Mă așteptam pe jumătate să se comporte ca parametrii meta_key / meta_value (nu știu de ce)..

t31os t31os
6 nov. 2010 10:24:58

@t31os - Da, WP_Query nu este implementat din păcate într-un mod atât de elegant. Sunt aproape 1200 de linii de cazuri speciale hardcodate.

MikeSchinkel MikeSchinkel
6 nov. 2010 19:06:30

"aproape 1200 de linii de cazuri speciale hardcodate."... m-a făcut să râd, a trebuit să +1 comentariul... ;)

t31os t31os
6 nov. 2010 19:19:19
Arată celelalte 1 comentarii
0

În retrospectivă, am combinat sugestiile lui MikeSchinkel și t31os. Este posibil să injectați acest lucru în interogările existente pe loc, dar necesită WordPress 3.1:

Plugin pentru a obține un flux RSS pentru articole care conțin orice termen dintr-o taxonomie

5 feb. 2011 18:06:56