If you have a collection of posts that need sorted or filtered by a repeater field, this can be a bit of a pain to query for.
The normal WP_Query meta_query arguments won’t work here.
To visualize this, lets imagine you have a custom post type of Trips.
Inside Trips, you have repeating fields for Dates of each trip and a checkbox if it should be Featured.
If you want to show ALL Trips that are marked as Featured and sorted by the Date of each trip, you’ll need to build an array with all your post_meta then output them via a loop.
Here’s what we need to do:
- Create an empty array to hold our post data
- Create a new WP_Query with any arguments we require
- Start the loopLoop through the repeater fields
- Optional: I added an if statement to filter by Featured only
- Add our post data to our array using key => value format
- Sort out data by date
- Output via foreach loop
A word on sorting in PHP
There are several built-in functions to sort, the best resource for quickly knowing which sort function to use is this chart:
Some helpful links to further reading about sorting options in PHP:
stackoverflow comment on Sort Mult-dimensional Array by Value
The full code below shows an example of a basic custom sort, which we can pass to usort if none of the pre-defined PHP sorting functions fit the bill.
You could achieve the same results with asort in this case, replacing both usort() and subval_sort function with just asort( $post_data );
The full code
Link to Github for a better view
<?php
// Create an empty array for storage
$post_data = array();
// Set arguments for your query
$args = array(
'post_type' => 'trips',
'posts_per_page' => 999
);
// Do our query with any arguments from above
$query = new WP_Query( $args );
if ( $query->have_posts() )
{
while ( $query->have_posts() )
{
$query->the_post();
// Setup our repeater
if( have_rows('trip_info') ):
while ( have_rows('trip_info') ) : the_row();
// Optional - Only get posts that match a true false within our repeater
if ( get_sub_field('featured_trip') )
{
// Build our array with the data we need using key => value
$post_data[] = array(
'title' => get_the_title(),
'date' => get_sub_field('trip_date')
);
}
endwhile;
endif;
}
}
// Custom function to use in our sort to list the items by date
function subval_sort( $a, $b )
{
if ( $a['date'] == $b['date'] )
return 0;
return $a['date'] < $b['date'] ? -1 : 1;
}
// Sort our multidimensional array by sub array value
usort( $post_data, 'subval_sort' );
// We can now work our data normally through easy to access methods
foreach ( $post_data as $post )
{
echo $post['title'] . ' ' ;
echo $post['date'];
echo '<br/>';
}