Sort By Custom Field

Discussion in 'WordPress' started by vanillaice, Mar 22, 2011.

  1. #1
    I had a custom field sort working, but I just found a bug where it was not displaying all the results for some reason. I have a review site, and want to sort by the overall score which is called 'rp_overall', and this is the code I had on my archive page which half-worked:

    <?php foreach(get_the_category() as $category) {
    		$cat = $category->cat_ID; }
    		query_posts('meta_key=rp_overall&orderby=meta_value&cat=' . $cat . '&order=DESC'); ?>
    Code (markup):
    Can anyone see what's wrong there? thank you!
     
    vanillaice, Mar 22, 2011 IP
  2. Cash Nebula

    Cash Nebula Peon

    Messages:
    1,197
    Likes Received:
    67
    Best Answers:
    0
    Trophy Points:
    0
    #2
    Closing bracket in the wrong spot. Try this:
    
    <?php foreach(get_the_category() as $category) {
    		$cat = $category->cat_ID;
    		query_posts('meta_key=rp_overall&orderby=meta_value&cat=' . $cat . '&order=DESC'); } ?>
    
    Code (markup):
     
    Cash Nebula, Mar 23, 2011 IP
  3. vanillaice

    vanillaice Peon

    Messages:
    42
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #3
    It's still doing weird stuff with the results.
    As it stands, I have 6 categories.
    - 3 of them have multiple results.
    - 2 of those said categories correctly display the results and order
    - The remaining category only displays 1 listing

    - Most of my tags are working except the one with the most results. It shows as 6 listings inside the WP area, but when clicked it only displays 2.

    The strange part is, some of the listings are showing in some places but not others, so it doesn't appear to be entry issues. I put the code right before to loop like this example:

    		
    <?php foreach(get_the_category() as $category) 
    {$cat = $category->cat_ID; query_posts('meta_key=rp_overall&orderby=meta_value&cat=' . $cat . '&order=DESC'); } ?>
    		
    <?php while (have_posts()) : the_post(); ?>
    Code (markup):
    Is there anything strange in that now?

    Thanks
     
    vanillaice, Mar 23, 2011 IP
  4. Cash Nebula

    Cash Nebula Peon

    Messages:
    1,197
    Likes Received:
    67
    Best Answers:
    0
    Trophy Points:
    0
    #4
    get_the_category() returns the categories of a single post. When used outside of a loop, I think that function returns the categories of the last post accessed by a loop.
    That could explain why you are getting weird results.

    Do you want to group the posts by category and then order each group by rating?
    I think that would require a custom database query, like the ones shown here:
    Wordpress Codex - Displaying Posts Using a Custom Select Query

    Or you could sort the posts using several arrays and loops. Either way, it's complicated work.
     
    Cash Nebula, Mar 23, 2011 IP
  5. vanillaice

    vanillaice Peon

    Messages:
    42
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #5
    Yes, I would like to have a regular blog (categories, tags, etc) which can be called on with archive.php, but then sort the results by my custom field. I had a feeling my code above was a hack work around for it, I'll have to look into that link you posted a bit and see if I can figure it out.

    Thank you!
     
    vanillaice, Mar 24, 2011 IP
  6. sirjonathan

    sirjonathan Peon

    Messages:
    11
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #6
    WP_Query may be just what you're looking for. Here's an example of the query (put this at the top of your template) to get your latest posts and then sort by your field. See notes for explanations.

    <?php // Let's get the data we need to loop through below
    
    $reviews = new WP_Query( 
    	array(
    		'post_type' => 'post', // Tell WordPress which post type we want - This could be "review"
    		'orderby' => 'meta_value', // We want to order the reviews by rating 	
    		'meta_key' => 'rp_overall', // Grab the overall score
    		'order' => 'DESC', // Show highest first. ASC is the other option.	
    		'posts_per_page' => '-1', // Let's show them all. 	
    		'meta_query' => array( // WordPress has all the results, now, return only the reviews with a rating of 3 or more
    			array(
    				'key' => 'rp_overall', // Check the start date field
    				'value' => '3', // Set the value (assuming a score scale of 1-5)
    				'compare' => '>=', // Return the ones greater than or equal to the "value" we set
    				'type' => 'NUMERIC,' // Let WordPress know we're working with numbers
    				)
    			)
    		)
    	);
    	
    // print_r($reviews); // Uncomment this to see the data WordPress is giving you above
    
    ?>
    PHP:
    Notice the additional use of meta_query. That lets you refine your results by that same field or additional custom fields. Feel free to remove it.

    To use the above in a loop, simply use the following on the same template:

    <?php if(!empty($reviews)){ // Check to make sure there are reviews ?>
    					
    	<?php while ($reviews->have_posts()) : $reviews->the_post(); 
    		$review_rating = get_post_meta($post->ID, 'rp_overall', true);
    		?>
    		<!-- Your Loop -->
    		<?php the_title(); ?>
                    Rating of: <?php echo $review_rating; ?> 			
    	<?php endwhile; ?>	
    <?php } ?>
    
    PHP:
     
    sirjonathan, Mar 24, 2011 IP
  7. vanillaice

    vanillaice Peon

    Messages:
    42
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #7
    Hey SirJonathan, I put that top code at the top of my archive page, and the loop in as well. It definitely did what was intended by pulling the data out and sorting it by the rp_overall, the problem I had was it pulled everything and displayed it on the page regardless of the category or tag I clicked.

    Is there a way to now take that data and display only matching category or tag?

    Thanks for doing all this btw!
     
    vanillaice, Mar 25, 2011 IP
  8. Cash Nebula

    Cash Nebula Peon

    Messages:
    1,197
    Likes Received:
    67
    Best Answers:
    0
    Trophy Points:
    0
    #8
    You could get the category ID from the query string and then only show posts that match it. I have not tested this so it may not work.
    
    <?php 
    	if (!empty($reviews)) :
    		global $query_string;
    		parse_str( $query_string, $args );
    		$catid = $args['cat'];
    		while ($reviews->have_posts()) : $reviews->the_post();
    			if ($post->cat_ID == $catid ) :
    				$review_rating = get_post_meta($post->ID, 'rp_overall', true); 
    ?>
    				<!-- Your Loop -->
    				<?php the_title(); ?>
    					Rating of: <?php echo $review_rating; ?>           
    			<?php endif; ?> 				
    		<?php endwhile; ?> 
    	<?php endif; ?> 
    
    PHP:
    But it would be better to avoid all that and just form a proper database query.
     
    Cash Nebula, Mar 25, 2011 IP