Mehrere orderby-Parameter in der Aktion pre_get_posts ()

In Bezug auf @ Ottos Antwort auf eine Frage, die ich auch über die Bestellung von mehreren Feldern hatte, hier ist, was er sagte:

Kann es nicht mit einer naiven WP_Query machen. Verwenden Sie den posts_orderby-Filter, um eine eigene Bestellzeichenfolge hinzuzufügen.

function my_order($orderby) { global $wpdb; return "{$wpdb->posts.post_author} ASC, {$wpdb->posts.post_date} DESC"; } add_filter( 'posts_orderby', 'my_order' ); $blah = new WP_Query(...); remove_filter( 'posts_orderby', 'my_order' ); 

-Otto

Dies scheint die Art und Weise zu sein, wie es in einem neuen Aufruf von WP_Query gemacht würde -> wie würde ich in einer pre_get_posts() Aktion mit zwei Meta-Feldern pre_get_posts() , mit einer Standardsortierung nach ?:

 function mouldings_sort($query) { if ($query->is_main_query() && is_tax(array('wood_types','profile_categories','combination_categories'))) { $query->set('meta_key', '_mouldings_dimensions_height'); $query->set('order', 'DESC'); $query->set('orderby','meta_value_num'); } } add_action('pre_get_posts','mouldings_sort'); 

Ich hatte vorher versucht, einfach ein weiteres Meta-Feld hinzuzufügen:

 $query->set('meta_key', array('_mouldings_dimensions_height', '_mouldings_dimension_width')); $query->set('orderby','meta_value_num'); 

mit einem Standard-Sortback des title als so:

  $query->set('orderby','meta_value_num title'); 

aber es sieht nicht so aus, als könnte meta_key Arrays akzeptieren und mein title Rückgriff geht zurück auf Ottos ursprüngliche Antwort zu diesem Thema. Jede Hilfe wäre sehr willkommen. Vielen Dank!

Solutions Collecting From Web of "Mehrere orderby-Parameter in der Aktion pre_get_posts ()"

Vergiss nie, dass es tatsächlich zwei Filter gibt

 // Add additional query args that are allowed by the API by default pre_get_posts // Modify the query herself posts_clauses // Inspect the resulting string - test this one in for eg phpMyAdmin posts_request 

Alles, was Sie mit dem pre_get_posts Filter erreichen können, sollte also dort gemacht werden. Der Rest sollte mit den posts_clauses (oder einem der spezifischeren Filter davor) geändert werden.

 // Modify the original query parts function wpse70214_pre_get_posts( $query ) { var_dump( $query ); return $query; } add_filter( 'pre_get_posts', 'wpse70214_pre_get_posts' ); // Modify the resulting query string parts function wpse70214_posts_clauses( $pieces ) { var_dump( $pieces ); return $pieces; } add_filter( 'posts_clauses', 'wpse70214_posts_clauses' ); // Then check the result function wpse70214_posts_request( $query_string ) { var_dump( $query_string ); return $query_string; } add_action( 'posts_request', 'wpse70214_posts_request' ); 

Ja, wie Otto sagte, Sie können keine sekundäre ORDER BY Klausel ohne einen benutzerdefinierten posts_orderby Filter haben. Wenn Sie wissen möchten, welche Abfrage Sie auf einem “pre_get_posts” haben, können Sie eine function erstellen, die den orderby-Filter zu posts_orderbby hinzufügt und ihn von pre_get_posts aufruft.

 /** * Posts orderby filter. The filter will be added using pre_get_posts outside the class * using the pre_get_posts action allows us to do checks for what page etc... * @return string, new MySQL ORDER BY clause */ function wpse_order_by() { global $wpdb; return $wpdb->prepare( "$wpdb->postmeta.meta_value+0 DESC, post_title DESC" ); } /** * Pre get posts filter for adding secondary fall back ORDER BY clause to MySql query * @uses remove_filter(), This filter removes itself after it runs to prevent it from affecting other queries on the same page. * @uses add_filter() * @param object|array $query the current $query object */ function wpse_post_order_pre( $query ) { if ($query->is_main_query() && is_tax(array('wood_types','profile_categories','combination_categories'))) { /** remove_filter() is used to prevent this affecting additional queries on the page */ remove_filter( current_filter(), __FUNCTION__ ); add_filter( 'posts_orderby', 'wpse_order_by' ); } } add_action( 'pre_get_posts', 'wpse_post_order_pre' );