2

Is it possible using WP_Query to return a filtered list of items based on the following criteria set? I seem to be struggling as there are numerous queries against custom fields.

Select all posts that are of type business_club (post_type)
Where the post has a zone of 'Asia' (meta_value)
Order by country ASC (meta_value)
then by town ASC (meta_value)
then by title (wp value)

Any help is greatly appreciated.

3 Answers 3

2

Did you try something like this:

$loop = new WP_Query( array( 
    'post_type' => 'business_club',
    'meta_value' => 'United Kingdom',
    'order' => 'ASC',
    'orderby' => 'meta_value',
    'meta_key' => 'zone'
 ) ); 
while ( $loop->have_posts() ) : $loop->the_post();

I don't know yet if you can do the then orderby town and title.

1
  • 1
    You'd have to do a custom join and a custom order by using the posts_join and posts_orderby filters Jan 8, 2011 at 6:32
2

If all results have the same zone, why would you want to order by zone?

As far as I know, you can't include two meta_keys in a single query. So you'll have to write the query to return the results ordered by title, save them in an array, and then resort the array into the order you need using PHP.

1
  • That was a mistake in the pseudo-code sample Gabriel, I've updated the example. Do you have any examples of sorting after the resultset has been returned?
    – WDuffy
    Jan 10, 2011 at 9:13
1

The way around it was to build a custom query. More information on this can be viewed on the Wordpress codex at http://codex.wordpress.org/Displaying_Posts_Using_a_Custom_Select_Query.

My final code looked as follows

<?php               
$row = 0;
$zone = $_GET['zone'];
if (!$zone) $zone = "United Kingdom";
?>

<table class="formattedTable" cellspacing="1" cellpadding="0">
<tr>
    <th width="140">Country</th>
    <th width="140">Town</th>
    <th>Club</th>
</tr>
<?php

$query = "
SELECT
  posts.*
FROM
  $wpdb->posts posts
INNER JOIN
  $wpdb->postmeta meta1 ON posts.ID = meta1.post_ID
INNER JOIN
  $wpdb->postmeta meta2 ON posts.ID = meta2.post_ID
INNER JOIN
  $wpdb->postmeta meta3 ON posts.ID = meta3.post_ID
WHERE
  posts.post_type = 'club' AND
  posts.post_status = 'publish' AND
  meta1.meta_key = '_club-zone' AND
  meta1.meta_value = '$zone' AND
  meta2.meta_key = '_club-country' AND
  meta3.meta_key = '_club-town'
ORDER BY
  meta2.meta_value,
  meta3.meta_value,
  posts.post_title";

$posts = $wpdb->get_results($query, object);        
if ($posts)
    foreach($posts as $post)
    {
        global $post;
        setup_postdata($post);

        echo '<tr class="' . ($row % 2 == 0 ? 'odd' : 'even') . '">';
        echo '<td>' . get_post_meta(get_the_ID(), '_club-country', true) . '</td>';
        echo '<td>' . get_post_meta(get_the_ID(), '_club-town', true) . '</td>';
        echo '<td><a href="' . get_permalink(get_the_ID()) . '">' . get_the_title() . '</a></td>';
        echo '</tr>';
        $row++;
    }

?>
</table>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.