This can be done using filters on the query. Here is an article with some sample code that might help:
http://wordpress.mcdspot.com/2013/01/25/sort-on-presence-of-custom-field-field-value-then-date/
Wow, this is way above my head. Let me try to make it simpler,
How can I query for all posts in a post type where a field is not null? I’m using this at the moement:
<?php
$args = array(
'posts_per_page' => -1,
'order' => 'ASC',
'orderby' => 'title',
'post_type' => 'store'
);
query_posts($args); if (have_posts()) : ?>
<?php while (have_posts()) : the_post(); ?>
<p class="directory">
<a href="<?php echo get_permalink(); ?>" title="<?php the_title(); ?>"><?php the_title(); ?></a></p>
<?php endwhile; ?>
<?php else : ?>
<h3 class="post-title">No Stores Found</h3>
<p>We're sorry, but there are no stores currently available for display. Please return soon.</p>
<p>
<a href="<?php echo get_option('home'); ?>">Return to the homepage</a></p>
<?php endif; wp_reset_query(); ?>
I think if I can see how to return posts where the field is null (and when it is not null as well), I should be fine.
Thanks
OK, I’ll try to make it simpler. Just change this:
<?php
$args = array(
'posts_per_page' => -1,
'order' => 'ASC',
'orderby' => 'title',
'post_type' => 'store'
);
to this:
<?php
// Sort posts in order on presence of a custom field,
// value of custom field, then date
$meta_key = 'auteur'; // The meta_key
// NOTE: The functions and add_filter() calls should really go in functions.php,
// but they will work here and are included here for convenience.
function mam_posts_fields ($fields) {
global $mam_global_fields;
// Make sure there is a leading comma
if ($mam_global_fields) $fields .= (preg_match('/^(\s+)?,/',$mam_global_fields)) ? $mam_global_fields : ", $mam_global_fields";
return $fields;
}
function mam_posts_join ($join) {
global $mam_global_join;
if ($mam_global_join) $join .= " $mam_global_join";
return $join;
}
function mam_posts_where ($where) {
global $mam_global_where;
if ($mam_global_where) $where .= " $mam_global_where";
return $where;
}
function mam_posts_orderby ($orderby) {
global $mam_global_orderby;
if ($mam_global_orderby) $orderby = $mam_global_orderby;
return $orderby;
}
add_filter('posts_fields','mam_posts_fields');
add_filter('posts_join','mam_posts_join');
add_filter('posts_where','mam_posts_where');
add_filter('posts_orderby','mam_posts_orderby');
global $wpdb,$wp_query;
$mam_global_fields = ', IF(ISNULL(pm.meta_id),9,1) as sort_key, pm.meta_value';
$mam_global_join = " LEFT JOIN $wpdb->postmeta pm ON ($wpdb->posts.ID = pm.post_id AND pm.meta_key = '$meta_key')";
$mam_global_orderby = "sort_key, pm.meta_value, $wpdb->posts.post_date DESC";
$args = array(
'posts_per_page' => -1,
'post_type' => 'store'
);
And put in your own key for $meta_key.
I really need to get better with PHP. Thanks for all your help so far. I tried the code above, modified the meta_key value, but the results weren’t sorted.
I was able to get it to work through a bit of a hack though, here’s how it looks, and here’s what I did:
<?php
$args = array(
'posts_per_page' => -1,
'order' => 'ASC',
'orderby' => 'title',
'post_type' => 'store'
);
query_posts($args); if (have_posts()) : ?>
<?php while (have_posts()) : the_post(); ?>
<?php $value = get_post_meta($post->ID, 'store_meta_phone', true); ?>
<?php if($value != '') : ?>
<p class="directory premium">
<a href="<?php echo get_permalink(); ?>" title="<?php the_title(); ?>"><?php the_title(); ?></a></p>
<?php endif; ?>
<?php endwhile; ?>
<?php endif; wp_reset_query(); ?>
<?php
$args2 = array(
'posts_per_page' => -1,
'order' => 'ASC',
'orderby' => 'title',
'post_type' => 'store'
);
query_posts($args2); if (have_posts()) : ?>
<?php while (have_posts()) : the_post(); ?>
<?php $value2 = get_post_meta($post->ID, 'store_meta_phone', true); ?>
<?php if(empty($value2)) : ?>
<p class="directory">
<a href="<?php echo get_permalink(); ?>" title="<?php the_title(); ?>"><?php the_title(); ?></a></p>
<?php endif; ?>
<?php endwhile; ?>
<?php else : ?>
<h3 class="post-title">No Stores Found</h3>
<p>We're sorry, but there are no stores currently available for display. Please return soon.</p>
<p>
<a href="<?php echo get_option('home'); ?>">Return to the homepage</a>
</p>
<p> </p>
<p> </p>
<p> </p>
<?php endif; wp_reset_query(); ?>
Basically I’m displaying some stores as preferred if there is a phone number stored, and the rest after if no phone number is present by running two queries. Is this a bad practice?