Please can someone help me write a custom loop that orders first by the contents of a custom field and second, alphabetically by post title.
I have a custom field associated with each post entitled 'Promote'.
When 'Promote' has a value of 'Yes', I would like those posts to appear first in the loop. Regular posts would follow promoted posts with both regular and promoted posted ordered alphabetically by post title.
All non-promoted posts will have a 'Promote' custom field value of 'No'.
The custom loop should retain standard WordPress pagination enabling manipulation via the 'Reading > Blog pages show at most X posts' feature in the WordPress admin.
Many thanks.
<strong>CLARIFICATION</strong>: the loop should be universal and work equally as a category loop, tag loop, search loop and index loop. Thanks.
Pau answers:
Here's my simple method for post_title to alphabetically ordered and your custom field value ordered and still retain the pagination function.
function custom_orderby($orderby){
return "meta_value DESC, post_title DESC";
}
add_filter('posts_orderby', 'custom_orderby');
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$args=array(
'paged' => $paged,
'meta_key' => 'promote'
);
query_posts($args);
insert it at the top of:
if ( have_posts() ) while ( have_posts() ) : the_post();
<strong>NOTE:</strong> this work anywhere that have loop
MagoryNET answers:
You have to make a custom query:
<?php
global $wpdb;
$querystr = "
SELECT wposts.*
FROM $wpdb->posts wposts, $wpdb->postmeta wpostmeta
WHERE wposts.ID = wpostmeta.post_id
AND wpostmeta.meta_key = 'Promote'
AND wposts.post_status = 'publish'
AND wposts.post_type = 'post'
ORDER BY wpostmeta.meta_value DESC, wposts.post_date DESC
";
$pageposts = $wpdb->get_results($querystr, OBJECT);
// start of the loop
<?php if ($pageposts): ?>
<?php global $post; ?>
<?php foreach ($pageposts as $post): ?>
<?php setup_postdata($post); ?>
// here is the loop
// end of the loop
<?php endforeach; ?>
<?php else : ?>
<h2 class="center">Not Found</h2>
<p class="center">Sorry, but you are looking for something that isn't here.</p>
<?php include (TEMPLATEPATH . "/searchform.php"); ?>
<?php endif; ?>
$pageposts = $wpdb->get_results($querystr, OBJECT);
?>
You should probably add an index on meta_key, meta_value pair and add some LIMIT (using $paged) to the query (probably $paged*15, 15 or sth - depending on your page size).
Jimish Gamit answers:
<?php
SELECT * FROM $wpdb->posts
LEFT JOIN $wpdb->postmeta ON($wpdb->posts.ID = $wpdb->postmeta.post_id)
WHERE $wpdb->postmeta.meta_key = 'Promote'
AND $wpdb->posts.post_status = 'publish'
AND $wpdb->posts.post_type = 'post'
ORDER BY $wpdb->postmeta.meta_value DESC,$wpdb->posts.post_date DESC ";
$pageposts = $wpdb->get_results($querystr, OBJECT); ?>
<?php if ($pageposts): ?>
<?php global $post; ?>
<?php foreach ($pageposts as $post): ?>
<?php setup_postdata($post); ?>
// here is the loop
// end of the loop
<?php endforeach; ?>
<?php else : ?>
<h2 class="center">Not Found</h2>
<p class="center">Sorry, but you are looking for something that isn't here.</p>
<?php include (TEMPLATEPATH . "/searchform.php"); ?>
<?php endif; ?>
$pageposts = $wpdb->get_results($querystr, OBJECT);
?>
Rok Don answers:
$querystr = "
SELECT wposts.*
FROM $wpdb->posts wposts, $wpdb->postmeta wpostmeta
WHERE wposts.ID = wpostmeta.post_id
AND wpostmeta.meta_key = 'Promote'
AND wposts.post_type = 'post'
ORDER BY wpostmeta.meta_value DESC
";
designbuildtest comments:
MagoryNET, Jimish Gamit & Rok Don, thank you, these all look very promising. Please could someone piece all the code together and include my loop (below)
<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<h2 class="entry-title"><a href="<?php the_permalink(); ?>" rel="bookmark"><?php the_title(); ?></a></h2>
<?php the_content(); ?>
</div>
Rok Don comments:
<?php
$querystr = "
SELECT wposts.*
FROM $wpdb->posts wposts, $wpdb->postmeta wpostmeta
WHERE wposts.ID = wpostmeta.post_id
AND wpostmeta.meta_key = 'Promote'
AND wposts.post_type = 'post'
ORDER BY wpostmeta.meta_value DESC
";
$pageposts = $wpdb->get_results($querystr, OBJECT);
if ($pageposts):
global $post;
foreach ($pageposts as $post):
setup_postdata($post); ?>
<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<h2 class="entry-title"><a href="<?php the_permalink(); ?>" rel="bookmark"><?php the_title(); ?></a></h2>
<?php the_content(); ?>
</div>
<?php endforeach;
else : ?>
<h2 class="center">Not Found</h2>
<p class="center">Sorry, but you are looking for something that isn't here.</p>
<?php endif; ?>