You could try using the posts_orderby
filter:
add_filter('pre_get_posts', 'sort_arc');
function sort_arc($q) {
if ($q->is_category() && $q->is_main_query()) {
$q->set('meta_key', 'the-year');
add_filter('posts_orderby', 'custom_posts_orderby');
}
return $q;
}
where
function custom_posts_orderby($orderby) {
global $wpdb;
return $wpdb->postmeta.".meta_value+0 DESC, ".$wpdb->posts .".post_title ASC";
}
takes care of the custom ordering. We use meta_value+0
from the meta_value_num
definition in /wp-includes/query.php
.
Update:
Here is one idea how you could try to combine the two hooks:
add_filter('pre_get_posts', 'custom_pre_get_posts');
function custom_pre_get_posts($q) {
if( $q->is_admin ) {
return $q;
}
if( !$q->is_main_query() ) {
//echo "DEBUG: !is_main_query() <pre>".print_r($q,true)."</pre>";
return $q;
}
if( !$q->is_archive() ) {
//echo "DEBUG: !is_archive() <pre>".print_r($q,true)."</pre>";
return $q;
}
if ($q->is_category() && !isset($_GET['sort']) ) {
$q->set('meta_key', 'the-year');
add_filter('posts_orderby', 'custom_posts_orderby');
//echo "DEBUG: is_category() <pre>".print_r($q,true)."</pre>";
return $q;
}
$custom_field = ( $_GET['sort'] ) ? stripslashes( $_GET['sort'] ) : '';
$custom_value = ( $_GET['sortorder'] ) ? stripslashes( $_GET['sortorder'] ) : '';
if( $custom_field ) {
$q->set( 'meta_key', $custom_field );
$q->set( 'orderby', $custom_field );
if( $custom_value ) {
$q->set( 'order', $custom_value );
//echo "DEBUG: custom_value <pre>".print_r($q,true)."</pre>";
return $q;
}
//echo "DEBUG: custom_field <pre>".print_r($q,true)."</pre>";
return $q;
}
//echo "DEBUG: else <pre>".print_r($q,true)."</pre>";
return $q;
}