Mit wp_query ist es möglich, nach Taxonomie zu sortieren?

Meine Frage ist einfach, ich verwende WP_Query, um einige benutzerdefinierte Posts zu erhalten, die nach einer Taxonomie mit tax_query filtern.

Nun möchte ich das Problem mit der Taxonomie anordnen, aber aus Dokumentation und Suche im Web kann ich keine Lösung finden.

Die orderby in WP_Query lässt Sie nach einer Reihe von Feldern sogar benutzerdefinierte Meta-Felder bestellen, aber es scheint keine Taxonomie zu unterstützen.

Irgendwelche Hinweise in die richtige Richtung?

Danke euch allen.

Solutions Collecting From Web of "Mit wp_query ist es möglich, nach Taxonomie zu sortieren?"

Nein, es ist nicht möglich, nach Taxonomie zu sortieren, weil das aus einer bestimmten Art von Standpunkt nicht viel Sinn ergibt.

Taxonomien sind Möglichkeiten, Dinge zu gruppieren. Der Punkt, eine Taxonomie auf Posts zu haben, wäre also wirklich, Begriffe in dieser Taxonomie zu haben, die zwischen Posts geteilt werden. Wenn eine Taxonomie Begriffe hätte, die nur für jeweils einen Post verwendet würden, würde dies die Taxonomie sinnlos machen. Und wenn die Begriffe so geteilt würden, wie sie sein sollten, dann würde das Ordnen durch sie nichts besonders Nützliches ergeben.

Was Sie in einer solchen Situation verwenden sollten, ist das Post-Meta. Sie können per Post-Meta bestellen, und es ist einzigartig für jeden Beitrag.

Edit: Das heißt, Sie können nach Taxonomie ordnen, indem Sie eine benutzerdefinierte SQL-Abfrage mit einem Filter erstellen, Sie können es einfach nicht von einem unmodifizierten WP_Query tun: http://scribu.net/wordpress/sortable-taxonomy-columns.html

Wenn Sie jedoch auf solche Dinge zurückgreifen müssen, ist Ihre Datenstruktur von Anfang an falsch. “Terms” in der Taxonomie sind keine tatsächlichen “Daten”. Die Begriffe selbst haben keine inhärente Bedeutung, sie sind nur Bezeichnungen für die bestimmte Gruppierung, die sie beschreiben. Wenn Sie sie als aussagekräftige Daten behandeln, haben Sie einen zugrunde liegenden Konstruktionserrors.

Taxonomien gruppieren Dinge, indem sie ihnen Begriffe zuweisen. Diese Gruppierung ist der springende Punkt von Taxonomien, die Begriffe sind nur hübsche Gesichter auf der Gruppierung. Wenn Sie aussagekräftige Metadaten für einen Beitrag haben, sollten Sie stattdessen das Post-Meta dafür verwenden. Und das können Sie bestellen, da post meta sowohl Schlüssel als auch Werte zum Speichern von Informationen verwendet. Bei einer Taxonomie speichern Sie nur Schlüssel, deren Werte die Beiträge sind, die nach diesem Begriff gruppiert sind.

Auf lange Sicht ist es einfacher, wenn Sie den richtigen Ansatz dafür verwenden. Während ich nicht sage, dass Sie mit der Taxonomie nicht etwas Seltsames tun können, machen Sie es auf lange Sicht einfach schwerer, es falsch einzusetzen.

Die akzeptierte Antwort für diese Frage ist inakzeptabel. Es ist unlogisch zu vermuten, dass die steuerliche Anordnung “keinen Sinn macht”. Die Antwort, die er gab, ergibt keinen Sinn.

Erwägen Sie, einen Menüpostentyp zu verwenden. Dann haben Sie eine benutzerdefinierte Steuer von “FoodCategories”. Die FoodCategories-Steuer hat die Begriffe “Frühstück”, “Mittagessen” und “Abendessen”. Wenn Sie eine Abfrage mit dem Parameter tax_query senden, haben Sie jetzt ein Ergebnis mit allen Begriffen, jedoch nach Post-Datum sortiert.

Um die richtige Reihenfolge relativ zu ihren Termen zu erhalten und dann auf dem Frontend entsprechend durch Trennen der Posts in ihre verschiedenen Kategorien anzuzeigen, müssen Sie die Ergebnismenge durchforsten und dann jeden einzelnen Post in der result set, um seine Begriffe zu finden und mit dem aktuellen Begriff zu vergleichen, in ein Array zu filtern und weiter zu machen. Dann müssen Sie das neue Array zur Anzeige erneut durchlaufen. Dies ist nicht produktiv.

Es wäre schön, wenn WP eine “tax__in” orderby Option hätte, wie es ein “post__in” tut, aber da dies nicht der Fall ist, müssen Sie entweder den oben genannten lächerlichen process machen; Passen Sie die Abfrage selbst über den Filter ‘posts_orderby’ und den Filter ‘posts_join’ an, um die Methode orderby anzupassen und den Ausdruck der Ergebnismenge hinzuzufügen. oder Sie müssen für jeden Begriff, nach dem Sie filtern, eine neue Abfrage in den HTML-Abschnitten im Vergleich zu diesen Begriffen erstellen.

Am effizientesten wäre es, die Abfragezeichenfolge über Filter zu ändern. Am einfachsten wäre es, drei separate Abfragen durchzuführen. Die WP-API sollte die steuerliche Bestellung oder alle restriktiven Abfrageparameter verarbeiten. Wenn Sie eine Abfrage basierend auf bestimmten Bedingungen einschränken, ist es sehr wahrscheinlich, dass viele unter denselben Bedingungen eine Bestellung aufgeben müssen.

Ja, aber es ist ziemlich involviert …

Fügen Sie zu functions.php in Ihrem Thema hinzu:

function orderby_tax_clauses( $clauses, $wp_query ) { global $wpdb; $taxonomies = get_taxonomies(); foreach ($taxonomies as $taxonomy) { if ( isset( $wp_query->query['orderby'] ) && $taxonomy == $wp_query->query['orderby'] ) { $clauses['join'] .=< <term_relationships} ON {$wpdb->posts}.ID={$wpdb->term_relationships}.object_id LEFT OUTER JOIN {$wpdb->term_taxonomy} USING (term_taxonomy_id) LEFT OUTER JOIN {$wpdb->terms} USING (term_id) SQL; $clauses['where'] .= " AND (taxonomy = '{$taxonomy}' OR taxonomy IS NULL)"; $clauses['groupby'] = "object_id"; $clauses['orderby'] = "GROUP_CONCAT({$wpdb->terms}.name ORDER BY name ASC) "; $clauses['orderby'] .= ( 'ASC' == strtoupper( $wp_query->get('order') ) ) ? 'ASC' : 'DESC'; } } return $clauses; } add_filter('posts_clauses', 'orderby_tax_clauses', 10, 2 ); 

Dies ist von einigen gefundenen Sachen und einigen Sachen, die ich selbst gemacht habe, freigestellt. Erklären ist ziemlich hart, aber das Endergebnis ist mit diesem Laufen, Sie können setzen? Orderby = (Taxonomie-Abfrage var) & Ordnung = ASC (oder DESC) und sie wird gleich ausziehen!

Ich komme hier zu spät zum Spiel, aber es gibt eine einfachere Art, dies zu tun.

Erstellen Sie Ihre Steueranfrage wie gewohnt.

 $tax_query = array(); $tax_query['relation']="OR"; $tax_query[] = array( 'taxonomy' => 'product_cat', 'field' => 'slug', 'terms' => $cat_terms, ); $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; 

Richten Sie Ihre Argumente für query_posts oder WP_Query ein

 $args = array( 'post_type'=>'post', 'posts_per_page'=>12, 'paged'=>$paged, 'tax_query' => $tax_query, ); 

Bevor Sie Ihren query_posts / WP_Query-Aufruf ausführen, haken Sie sich in den orderby-Filter ein und überschreiben Sie ihn

 add_filter('posts_orderby', 'edit_posts_orderby'); function edit_posts_orderby($orderby_statement) { $orderby_statement = " term_taxonomy_id ASC "; return $orderby_statement; } query_posts($args); remove_filter('posts_orderby', 'edit_posts_orderby'); 

Vergessen Sie nicht, den Filter nachträglich zu entfernen …

Dies funktioniert b / c die Tax_Query erstellt die Joins etc. für Sie, Sie müssen nur nach einem der Felder aus dem Join bestellen.

Nun, ich möchte meine Erfahrung im Sortieren von benutzerdefinierten Post-Typen nach Kategorie / Taxonomie offen legen.

DAS NETZ

  1. Eine Reisebüro-Website, die auf WordPress läuft
  2. Hauptinhalt des benutzerdefinierten Beitragstyps “Ruta”
  3. Taxonomie mit dieser Struktur Art des Reisens> Kontinent> Land

DER FALL

In Archivlisten-Seiten wollte der Client die Posts nach sortiert haben

  1. Der Kontinent, geordnet nach Anzahl der Routen auf jedem.
  2. Das Land, alphabetisch geordnet.

DIE SCHRITTE

Zuerst erhalte ich die Anfrage von der unmodifizierten Archivseitenabfrage, die wie folgt war:

 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 (5,6,7,8,9,10,11,12,13,15,16,17,18,19,20,21,22,23,25,26,28,29,31,32,33,35,38,95,101,102,193) ) AND wp_posts.post_type IN ('ruta', 'nav_menu_item') AND (wp_posts.post_status = 'publish' OR wp_posts.post_author = 45 AND wp_posts.post_status = 'private') GROUP BY wp_posts.ID ORDER BY wp_posts.post_date DESC LIMIT 0, 20 

Zweitens habe ich den SQL-Code in Sequel Pro gegen die database bearbeitet, um meine Bedürfnisse zu erfüllen. Ich komme damit (ja, wahrscheinlich kann es verbessert werden: mein Wissen über MySQL ist nicht hervorragend):

 SELECT SQL_CALC_FOUND_ROWS wp_posts.ID, tt1.parent AS pare, ( SELECT COUNT(*) FROM wp_posts INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) INNER JOIN wp_term_taxonomy AS tt1 ON ( tt1.term_taxonomy_id = wp_term_relationships.term_taxonomy_id ) INNER JOIN wp_term_taxonomy AS tt2 ON ( tt2.term_taxonomy_id = tt1.term_taxonomy_id ) WHERE 1=1 AND tt1.parent = pare ) AS Total FROM wp_posts INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) INNER JOIN wp_term_taxonomy AS tt1 ON ( tt1.term_taxonomy_id = wp_term_relationships.term_taxonomy_id ) INNER JOIN wp_terms ON ( tt1.term_id = wp_terms.term_id ) WHERE 1=1 AND ( wp_term_relationships.term_taxonomy_id IN (5,6,7,8,9,10,11,12,13,15,16,17,18,19,20,21,22,23,25,26,28,29,31,32,33,35,38,95,101,102,193) ) AND wp_posts.post_type IN ('ruta', 'nav_menu_item') AND (wp_posts.post_status = 'publish' OR wp_posts.post_author = 45 AND wp_posts.post_status = 'private') GROUP BY wp_posts.ID ORDER BY total DESC, wp_terms.name 

Drittens habe ich die Abfrage in der Datei functions.php mit drei Filtern verknüpft: posts_fields, posts_join und posts_orderby

Der Code in functions.php:

 function xc_query_fields( $fields ) { $fields = "wp_posts.ID, wp_posts.post_title, wp_terms.name, tt1.parent AS pare, ( SELECT COUNT(*) FROM wp_posts INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) INNER JOIN wp_term_taxonomy AS tt1 ON ( tt1.term_taxonomy_id = wp_term_relationships.term_taxonomy_id ) INNER JOIN wp_term_taxonomy AS tt2 ON ( tt2.term_taxonomy_id = tt1.term_taxonomy_id ) WHERE 1=1 AND tt1.parent = pare ) AS Total"; return $fields; } function xc_query_joins( $join ) { $join .= "INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id) INNER JOIN wp_term_taxonomy AS tt1 ON ( tt1.term_taxonomy_id = wp_term_relationships.term_taxonomy_id ) INNER JOIN wp_terms ON ( tt1.term_id = wp_terms.term_id )"; return $join; } function xc_query_orderby( $join ) { $join = "total DESC, wp_terms.name "; return $join; } 

Schließlich habe ich die Filter aus dem pre_get_post-Hook unter bestimmten Bedingungen ausgetriggers

 function filtra_queries( $query ) { if ( is_archive() && $query->is_main_query() && !is_admin() ) { $rutes = array('viajes-privados', 'asia', 'africa', 'oceania', 'america', 'oriente-proximo'); if ( in_array( $query->get('category_name'), $rutes ) ) { add_filter( 'posts_fields', 'xc_query_fields' ); add_filter( 'posts_join', 'xc_query_joins' ); add_filter( 'posts_orderby', 'xc_query_orderby' ); }// end if in_array }// end if is_archive } add_filter('pre_get_posts', 'filtra_queries'); 

Hoffe, das kann jemandem helfen

Hier ist die Lösung, die ich für dieses spezielle Problem verwendet habe. Diese Lösung eignet sich für extreme Fälle, in denen es nicht möglich ist, einen pre_get_posts Filter zu verwenden, und bei dem eine pre_get_posts vorhanden ist ( pre_get_posts : WooCommerce):

 global $wpdb; $taxonomies = array('my-tax-1', 'my-tax-2', 'my-tax-3'); $orderby = "'".implode("', '", array_keys($taxonomies))."'"; $id_sql = $GLOBALS['wp_query']->request; $id_sql = preg_replace('/LIMIT\s+\d+\s?,?\s\d*/', '', $id_sql); $id_sql = str_replace('SQL_CALC_FOUND_ROWS', '', $id_sql); $term_sql = "SELECT tt.taxonomy AS `taxonomy`, t.name AS `term_name`, t.slug AS `term_slug`, count(*) AS `term_count` FROM ({$id_sql}) p JOIN wp_term_relationships tr ON p.ID = tr.object_id JOIN wp_term_taxonomy tt ON tr.term_taxonomy_id = tt.term_taxonomy_id JOIN wp_terms t ON tt.term_id = t.term_id WHERE tt.taxonomy IN ({$orderby}) GROUP BY t.slug ORDER BY FIELD(tt.taxonomy, {$orderby})"; // Add further specific ordering here $results = $wpdb->get_results($term_sql, ARRAY_A); 

Ich habe dies verwendet, um ein Navigationsmenü zu erstellen, das nach Taxonomie, Begriff und Anzahl der Posts pro Term geordnet ist.

Wenn Sie die Posts einfach haben wollen, ändern Sie die Abfrage in SELECT p.* Und GROUP BY p.ID

Ich hatte ein sehr ähnliches Problem, mit dem ich mich beschäftigte: Ich möchte ein benutzerdefiniertes Post-Typ-Archiv (Zeitschriftenartikel) nach einer benutzerdefinierten Taxonomie (Ausgaben) bestellen. Ich leite niemals SQL-Abfragen auf meiner Site – und normalerweise, wenn Sie wie diese anderen Antworten sind – müssen Sie Ihren Ansatz überdenken.

PROBLEME:

1) WordPress erlaubt es Ihnen nicht, Taxonomien auf intelligente Weise zu ordnen.

2) WordPress erlaubt nur nicht die Verwendung von Taxonomien auf post-type WP_Query (wie von Otto ausgeschrieben).

LÖSUNGEN:

1) Sortieren von Taxonomien wird am besten durch das Custom Taxonomy Order NE Plugin im Moment durchgeführt. Es erlaubt Ihnen, die Taxonomie über WYSIWYG in wp-admin zu bestellen, das ist nicht, wie ich es tun würde, aber ich habe nichts besseres gefunden.

Wenn Sie das Plugin einrichten, werden Sie etwas erhalten, was ich hier gemacht habe. Notieren Sie sich die Option Auto-sort Queries of this Taxonomy – setzen Sie dies auf Custom Order as Defined Above ; Das bringt dir die Bestellung, die du brauchst. Bildschirmfoto:

Benutzerdefinierte Taxonomie-Reihenfolge NE-Anzeige

2) Wenn eine sortierte Taxonomie vorhanden ist, können Sie jetzt eine Reihe von WP_Query-Aufrufen erstellen, die jeden Begriff durchlaufen, wodurch effektiv ein Archiv erstellt wird, das nach der Taxonomie geordnet ist. Verwenden Sie get_terms() , um ein Array aller Steuerbegriffe zu erstellen, und führen Sie dann einen foreach für jeden Begriff aus. Dadurch wird für jedes WP_Query eine WP_Query erstellt, die alle Posts für einen bestimmten Term WP_Query , wodurch effektiv ein nach Taxonomieterm geordnetes Archiv erstellt wird. Code, um dies zu ermöglichen:

  // Get your terms and put them into an array $issue_terms = get_terms([ 'taxonomy' => 'issues', 'hide_empty' => false, ]); // Run foreach over each term to setup query and display for posts foreach ($issue_terms as $issue_term) { $the_query = new WP_Query( array( 'post_type' => 'post', 'tax_query' => array( array( 'taxonomy' => 'issues', 'field' => 'slug', 'terms' => array( $issue_term->slug ), 'operator' => 'IN' ) ) ) ); // Run loop over each query while($the_query->have_posts()) : $the_query->the_post(); // YOUR TEMPLATE OUTPUT FOR EACH POST endwhile; } 

Zugehörige Informationen auf dieser Website: Zeigen Sie alle Posts in einem benutzerdefinierten Post-Typ an, der nach einer benutzerdefinierten Taxonomie gruppiert ist

Ich bin mir nicht sicher, warum alle Lösungen hier ziemlich übertrieben sind. OK, es ist vor einem halben Jahrzehnt, aber ich führe gerade den folgenden Code aus und es funktioniert:

  < ?php // Default $wheels_args = array( 'post_type' => 'wheels', 'posts_per_page' => '96', 'orderby' => 'taxonomy, name', // Just enter 2 parameters here, seprated by comma 'order'=>'ASC' ); $loop = new WP_Query($wheels_args); ?> 

Dies sortiert die Taxonomien Ihres CPT zuerst nach seiner Taxonomie in alphabetischer Reihenfolge und innerhalb dieser Taxonomiegruppen nach alphabetischer Reihenfolge.

Es ist wie eine Abfrage vor der Abfrage, wird aber nicht stören, wenn wir nicht zu viele Posts abfragen … Die Idee ist, die Hauptabfrage so zu ändern, dass wir nicht einmal zu Templates gehen und neue Abfragen erzeugen müssen Schleifen …

 function grouped_by_taxonomy_main_query( $query ) { if ( $query->is_home() && $query->is_main_query() ) { // Run only on the homepage $post_ids = array(); $terms = get_terms('my_custom_taxonomy'); foreach ( $terms as $term ) { $post_ids = array_merge( $post_ids, get_posts( array( 'posts_per_page' => 4, // as you wish... 'post_type' => 'my_custom_post_type', // If needed... Default is posts 'fields' => 'ids', // we only want the ids to use later in 'post__in' 'tax_query' => array( array( 'taxonomy' => $term->taxonomy, 'field' => 'term_id', 'terms' => $term->term_id, )))) // getting posts in the current term ); } $query->query_vars['post_type'] = 'my_custom_post_type'; // Again, if needed... Default is posts $query->query_vars['posts_per_page'] = 16; // If needed... $query->query_vars['post__in'] = $post_ids; // Filtering with the post ids we've obtained above $query->query_vars['orderby'] = 'post__in'; // Here we keep the order we generated in the terms loop $query->query_vars['ignore_sticky_posts'] = 1; // If you dont want your sticky posts to change the order } } // Hook my above function to the pre_get_posts action add_action( 'pre_get_posts', 'grouped_by_taxonomy_main_query' );