Unter Bezugnahme auf @ Ottos Antwort auf eine Frage, die ich auch zum Bestellen nach mehreren Feldern hatte, sagte er Folgendes:
Mit einer naiven WP_Query geht das nicht. Verwenden Sie den Filter posts_orderby, um Ihre 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 dies in einem neuen Aufruf von WP_Query geschehen würde -> wie würde ich dasselbe in einer pre_get_posts()
-Aktion mit zwei Metafeldern mit einer Standard-Sortierung von ?:
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 zuvor versucht, einfach in ein anderes Metafeld wie folgt einzufügen:
$query->set('meta_key', array('_mouldings_dimensions_height', '_mouldings_dimension_width'));
$query->set('orderby','meta_value_num');
mit einem Standardsortback von title
als so:
$query->set('orderby','meta_value_num title');
aber es sieht nicht so aus, als ob meta_key
Arrays akzeptieren kann und mein title
-Fallback geht auf Ottos ursprüngliche Antwort in dieser Angelegenheit zurück. Jede Hilfe wäre sehr dankbar. Vielen Dank!
Vergiss niemals, 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 e.g. phpMyAdmin
posts_request
Alles, was Sie mit dem pre_get_posts
-Filter erreichen können, sollten Sie dort tun. Der Rest sollte mit dem posts_clauses
(oder einem der vorher genaueren Filter) 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 Funktion erstellen, die posts_orderby den orderby-Filter hinzufügt und von pre_get_posts aus 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' );