Benutzerdefinierte Taxonomie WP_Query für alle Begriffe in einer Taxonomie?

8

Gibt es eine einfache Möglichkeit, Beiträge abzufragen, die mit einem Begriff aus einer bestimmten Taxonomie versehen sind?

Ich kenne diese Technik:

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

Aber ich möchte entweder einen Platzhalter anstelle von term_slug oder nur eine leere Zeichenfolge übergeben. Dann würde ich alle Beiträge erhalten, die mit einem Begriff in dieser Taxonomie gekennzeichnet sind, nicht nur mit einem bestimmten Begriff.

Danke für deine Hilfe, Dave

Dave Morris
quelle

Antworten:

22

Ich bin auf eine ähnliche Situation gestoßen, Dave. Dieser Code hat den Trick für meine Zwecke getan. Es ist nicht die schlankste Option der Welt, aber es macht den Job gut:

// Get all term ID's in a given taxonomy
$taxonomy = 'taxonomy_name';
$taxonomy_terms = get_terms( $taxonomy, array(
    'hide_empty' => 0,
    'fields' => 'ids'
) );

// Use the new tax_query WP_Query argument (as of 3.1)
$taxonomy_query = new WP_Query( array(
    'tax_query' => array(
        array(
            'taxonomy' => $taxonomy,
            'field' => 'id',
            'terms' => $taxonomy_terms,
        ),
    ),
) );

Hoffentlich hilft dies Ihnen oder anderen Personen, bei denen das Problem auftritt.

Kevin

Kevin Leary
quelle
Das war sehr hilfreich für mich. Danke @kevinlearynet
Tyrun
Noch heute relativ
user1676224
7

So etwas könnte funktionieren:

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

Grundsätzlich fragen Sie nach einem Beitrag, der einem Begriff in Ihrer_Custom_taxonomy zugewiesen ist.

laurenfs132
quelle
4

Hallo @ Dave Morris:

Sie haben Recht, WordPress entscheidet, wenn Sie keinen Begriff haben, wird Ihre Taxonomie einfach ignoriert.

Es gibt drei (3) Hauptansätze, die Sie ausprobieren können:

  1. Verwenden Sie eine vollständige SQL-Abfrage mit $wpdb->get_results(),

  2. Holen Sie sich eine Liste von $post->IDs für alle Beiträge in Ihrer Taxonomie und übergeben Sie sie dann mit dem 'post__id'Argument oder

  3. Kommentieren Sie die von SQL verwendete SQLWP_Query mit einem der Hooks, mit denen Sie eine SQL hinzufügen können, die INNER JOINauf die Taxonomietabellen verweist.

Ich versuche, vollständiges SQL in WordPress zu vermeiden, bis entweder nicht geholfen werden kann oder einfach eine Liste mit IDs zurückgegeben wird. Und in diesem Fall würde ich es vermeiden, eine Liste von $post-IDs zur Verwendung mit dem 'post__id'Argument abzurufen, da dies zu Leistungsproblemen und sogar zu Speicherproblemen führen könnte, wenn Sie viele Beiträge hätten. Damit haben wir Platz 3.

Ich habe eine Klasse erstellt auszudehnenWP_Query genannt , PostsByTaxonomydie verwendet den 'posts_join"Haken. Sie können es hier sehen:

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

Sie würden diese Klasse wie unten gezeigt aufrufen. Das Argument 'taxonomy'ist eine erforderlich , aber Sie können jeder passieren (alle?) Die anderen Parameter , die WP_Queryauch erwartet, wie zum Beispiel 'posts_per_page':

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

Sie können die PostsByTaxonomyKlasse in die functions.phpDatei Ihres Themas kopieren oder sie in einer .phpDatei eines Plugins verwenden, das Sie möglicherweise schreiben.

Wenn Sie es schnell testen möchten, habe ich eine eigenständige Version des Codes in Gist veröffentlicht, die Sie herunterladen und in das Stammverzeichnis Ihres Webservers kopieren können test.php, für Ihren Anwendungsfall ändern und dann über eine URL wie Ihren Browser anfordern können http://example.com/test.php.

AKTUALISIEREN

Versuchen Sie Folgendes, um Sticky Posts aus den in der Abfrage enthaltenen Posts zu entfernen :

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

Oder wenn es Ihnen wichtig ist, dass die PostsByTaxonomyKlasse niemals klebrige Beiträge enthält, können Sie sie in den Konstruktor einfügen:

  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 Sticky Posts
    unset($args['taxonomy']);
    parent::query($args);
  }

UPDATE 2

Nach dem Posten der oben genannten Informationen habe ich erfahren, dass 'caller_get_posts' veraltet ist und 'ignore_sticky_posts'in WordPress 3.1 verwendet wird.

MikeSchinkel
quelle
Mike, danke für deine Hilfe. Ich kann das aus irgendeinem Grund nicht zum Laufen bringen. Es werden nicht nur Beiträge mit Begriffen zurückgegeben, die aus meiner benutzerdefinierten Taxonomie zugewiesen wurden. Es scheint immer andere Beiträge zurückzugeben. Es werden jedoch nicht alle Beiträge zurückgegeben, sodass definitiv etwas unternommen wird. Kann ich die Funktion $ query-> have_posts () zum Iterieren verwenden? Keine der beiden Methoden scheint für mich so oder so zu funktionieren.
Dave Morris
Ah, das ist interessant. Ich habe die Abfrage im MySQL-Protokoll gefunden, die die beiden erwarteten Beiträge enthält, und sie funktioniert. Aber aus irgendeinem Grund kommen fünf Beiträge zurück, wenn ich $ query-> posts durchlaufe. Das einzige andere, was mir auffällt, ist, dass direkt nach dem Ausführen der Abfrage für benutzerdefinierte Taxonomie-Posts eine weitere Abfrage ausgeführt wird, die drei weitere Posts anhand ihrer post_id erfasst. Und dann werden wohl alle fünf Beiträge in einem Ergebnisarray zusammengefasst.
Dave Morris
Ich glaube, ich habe es herausgefunden. Diese benutzerdefinierte Abfrage scheint klebrige Beiträge zu enthalten, obwohl sie nicht in dieser benutzerdefinierten Taxonomie enthalten sind. Irgendwelche Ideen, wie man klebrige Posts richtig honoriert oder zumindest aus dieser speziellen Abfrage herausholt? Vielen Dank, Dave
Dave Morris
Nun, sie sind "klebrig" , oder? :) Es ist seltsames Verhalten, denke ich, aber wenn Sie es verwenden caller_get_posts=1und sie verschwinden sollten: codex.wordpress.org/Function_Reference/… Hoffe, das hilft.
MikeSchinkel
Das if(isset($query->posts_by_taxonomy))ist ein schöner Trick, um die objektorientierte Methodik mit der Hook-Methodik von WordPress zu kombinieren.
Jan Fabry
1

Sie sollten nur in der Lage sein, die Taxonomie festzulegen und zu negieren, um einen Begriff einzuschließen.

Z.B.

<?php
$your_query = new WP_query;
$your_query->query( array( 'taxonomy' => 'your-taxonomy-name' ) );
?>

Dies entspricht in etwa der Abfrage, die ein Taxonomiearchiv ausführt.

t31os
quelle
Das geht nicht
Dave Morris
Zeile 1432 von query.php prüft, ob Taxonomie ODER Begriff leer sind, sodass Sie nicht einfach einen Slug übergeben können ... Irgendwelche anderen Ideen?
Dave Morris
@ t31os - Das war vielleicht auch die erste Reaktion; Ich bin tatsächlich mehr als einmal davon gestolpert, seit ich es immer wieder vergesse. Aber @ Dave Morris hat recht; Wenn es sich nicht um ein Taxonomie / Term-Paar handelt, wird es WP_Queryeinfach weggeworfen.
MikeSchinkel
6
@ t31os - Yup, WP_Queryist leider nicht so elegant implementiert. Es sind fast 1200 Zeilen fest codierter Sonderfälle.
MikeSchinkel
3
"Fast 1200 Zeilen fest codierter Sonderfälle." ... das hat mich lol gemacht, musste +1 den Kommentar ...;)
t31os