Unless you use ‘meta_key=my_meta_key’ in your query, you must use a JOIN filter to join the postmeta table so the meta_key/value will be available for the orderby filter.
Thread Starter
gab.ro
(@gabro)
Wow! I can’t believe I didn’t know about the posts_join
filter. Thanks!
Hey guys,
Picking up this thread. Hopefully someone will be able to help.
Here’s my query:
$args = array(
'post_type' => array( 'projects', 'post' ),
'posts_per_page' => -1,
'post_status' => 'publish'
'orderby' => 'meta_value',
'order' => 'DESC',
'meta_key' => 'code'
);
$projects = new WP_Query( $args );
My problem is the posts don’t have the meta_key of code so they won’t appear in my loop. I’m thinking that I can use the posts_orderby filter along with a couple other filters to get the job done. Only problem, I can’t figure out how to setup the filters. Any help?
Many thanks,
Jacob
See the article I referenced above for the filter functions.
You will need to eliminate the ‘orderby’, ‘order’, and ‘meta_key’ parameters from $args and handle the meta value in the filters.
This is UNTESTED.
Create a sort_key field with the fields filter (change the 0 to 9999999′ if you want missing code’s to sort before the projects, assuming order is DESC):
$mam_global_fields = ', IFNULL(pm.meta_value,0) AS sort_key';
Set the join filter to join the postmeta table:
$mam_global_join = " LEFT JOIN $wpdb->postmeta pm ON (pm.post_id = $wpdb->posts.ID AND pm.meta_key = 'code')";
Set the order to the sort_key:
$mam_global_orderby = 'sort_key DESC';
Thanks vtxyzzy,
I really appreciate your response!
Here’s what I’ve done:
in my front-page template:
$args = array(
'post_type' => array( 'projects', 'post' ),
'posts_per_page' => -1,
'post_status' => 'publish'
);
$mam_global_fields = ', IFNULL(pm.meta_value,0) AS sort_key';
$mam_global_join = " LEFT JOIN $wpdb->postmeta pm ON (pm.post_id = $wpdb->posts.ID AND pm.meta_key = 'code')";
$mam_global_orderby = 'sort_key DESC';
$projects = new WP_Query( $args );
In my functions.php:
function mam_posts_fields($fields) {
global $mam_global_fields;
if ( $mam_global_fields ) {
$fields .= ( preg_match('/^(\s+)?,/', $mam_global_fields) ) ? $mam_global_fields : ", $mam_global_fields";
}
return ( $fields ) ? $fields : '';
}
function mam_posts_join($join) {
global $mam_global_join;
if ( $mam_global_join && $join ) {
$join .= ' ' . $mam_global_join;
}
return ( $join ) ? $join : '';
}
function mam_posts_orderby($orderby) {
global $mam_global_orderby;
if ( $mam_global_orderby && $orderby ) {
$orderby = $mam_global_orderby;
}
return ( $orderby ) ? $orderby : '';
}
add_filter( 'posts_fields', 'mam_posts_fields' );
add_filter( 'posts_join', 'mam_posts_join' );
add_filter( 'posts_orderby', 'mam_posts_orderby' );
When I load the page, I get an error:
Parse error: syntax error, unexpected T_VARIABLE in …/wp-content/themes/ncm/functions.php on line 246
Which is this variable: global $mam_global_fields;
Can’t find any syntax errors, but no matter what I do, I can’t get the page to load with this code. Any ideas?
Thanks again,
Jacob
When I copy the code you posted and compile it, I get no errors either. The actual error may be on an earlier line. Put your functions.php file in a pastebin and post a link to it here.
You’re quick! Much appreciated.
http://pastebin.com/327Pvcj2
When I remove the new code, everything works fine.
Thanks again for your help. This topic has eluded me for some time.
-J
Don’t know what is going on, but in the pastebin there is no line 246. It ends on 215.
I cleaned out a bunch of commented functions that I use on some sites. It’s kind of a catch all functions.php that I use on all my sites. Would you like me to repost with all of the commented code?
-J
I get no errors on the code you posted, so I am at a loss to explain the problem.
Have you tried using just the code you posted?
I’ll give it a try right now. Did you update to 3.4, yet?
Not yet, I am in the middle of a couple of projects and don’t have time right now to back everything up on multiple sites. Besides, I have not tested it yet on any of my non-production sites.