Reputation: 637
I'm trying to get sorted list of posts using get_posts
by meta value and the order of meta value is given in array.
This is what I currently have.
$stores = get_posts(array(
'post_type' => 'stores',
'post_status' => 'publish',
'posts_per_page' => -1,
'fields' => 'ids', // I only need the ID's of posts
'orderby' => 'meta_value',
'meta_key' => 'state',
'order' => 'ASC'
));
This returns the array of posts sorted by meta_value
in ASCENDING alphabetical order.
I have an array of possible values for 'meta_key' => 'state'
, i.e. array('State1', 'State2', 'State3')
I want to set order so that all stores which has meta value State1
appears first, then from State2
and after that State3
I can't use order by numeric value and alphabetical value as state names are gonna be random.
I found one post here, it is using mera_query_orderby
. I can't find any documentation for this and tried it, but it's not working. It returns posts ordered by ID.
Any help would be appreciated. Thanks
EDIT:
I added the meta_query_orderby
filters in functions.php
And the updated code I used from EXAMPLE 2, is like:
$stores = get_posts(array(
'post_type' => 'stores',
'post_status' => 'publish',
'posts_per_page' => -1,
'fields' => 'ids',
'order' => 'ASC',
'meta_query' => array(
array(
'key' => 'state', // Custom field key.
'value' => array("CState1", "AState2", "BState3")
)
),
'meta_query_orderby' => array(
array(
'key' => 'state', // (required) Custom field key.
'value' => array("CState1", "AState2", "BState3")
)
)
));
Upvotes: 2
Views: 7772
Reputation: 570
/*Display posts of type 'stores', ordered by 'state', and filtered to show only states.*/
$args = array(
'post_type' => 'stores',
'meta_key' => 'state',
'orderby' => 'meta_value_num',
'order' => 'ASC',
'meta_query' => array(
array(
'key' => 'state',
'value' => array( 'State1', 'State2', 'State3'),
'compare' => 'IN',
),
),
);
$query = new WP_Query( $args );
Upvotes: 0
Reputation: 15620
I have an array of possible values for
'meta_key' => 'state'
, i.e.array('State1', 'State2', 'State3')
If you want to sort the posts by the meta value in the exact order as in the above array, you can use a custom WP_Query
parameter (to set the meta/sort values) and the posts_orderby
filter to customize the ORDER BY
clause, and in that clause, you would be using the FIELD()
function in MySQL.
Step 1
Add this code to your plugin or theme (if theme, you'd add the code to the theme functions file):
add_filter( 'posts_orderby', 'posts_orderby_meta_value_list', 10, 2 );
function posts_orderby_meta_value_list( $orderby, $query ) {
$key = 'meta_value_list';
if ( $key === $query->get( 'orderby' ) &&
( $list = $query->get( $key ) ) ) {
global $wpdb;
$list = "'" . implode( wp_parse_list( $list ), "', '" ) . "'";
return "FIELD( $wpdb->postmeta.meta_value, $list )";
}
return $orderby;
}
Step 2
When making your post queries, set the orderby
to meta_value_list
and add meta_value_list
to the query parameters — if you're using get_posts()
, make sure suppress_filters
is set to false
:
$stores = get_posts( array(
'post_type' => 'stores',
'post_status' => 'publish',
'posts_per_page' => -1,
'fields' => 'ids', // get just the ID's of posts
'meta_key' => 'state',
'orderby' => 'meta_value_list',
'meta_value_list' => array( 'State1', 'State2', 'State3', '' ),
'suppress_filters' => false,
) );
PS: I the added ''
to the array so that posts where the metadata is (''
) (i.e. exists in the database, but the value is empty) would be placed at the bottom of the results.
Tried and tested working, but note that the above solution is only for single orderby
, which means array is not supported.
Upvotes: 2