0

Is there a way to allow for multiple meta value orderby clauses in a WP Query? I have a query which retrieves records between meta keys start/end, and orders them ascending. I’m adding a new key for is_featured, and I’d like any records with a value of ‘Yes’ to be shown at the top, then display all records in ascending date order.

Given the following data:

record 01
    start: 11-04
    end: 11-20
    featured: No
record 02
    start: 11-06
    end: 11-20
    featured: Yes
record 03
    start: 11-08
    end: 11-20
    featured: No
record 04
    start: 11-10
    end: 11-20
    featured: Yes

I’d like the records to be in this order

Record 02
Record 04
Record 01
Record 03

This is the code I’m using right now.

$args = array(
    'meta_key'       => 'campaign_end_date',
    'orderby'        => 'meta_value_num',
    'order' => 'ASC',
    'meta_query'  => array(
        array(
            'key'        => 'campaign_start_date',
            'compare'    => '<=',
            'value'      => $in_three_days,
        ),
        array(
            'key'        => 'campaign_end_date',
            'compare'    => '>=',
            'value'      => $today,
        ),
    ),
);

I've tried passing in an array to the orderby key like so, but that doesn't work.

array(
    'meta_key' => 'campaign_end_date',
    'orderby' => array(
        'is_featured' => 'DESC',
        'meta_value_num' => 'ASC',
    ),
    'order' => 'ASC',
);

I’m able to get the featured posts at the top, but because I’m only using a single DESC, all posts are in descending order.

The goal is to have the bottom right element in this screenshot showing up at the top left corner, and everything else in the same order as they currently are.

example screenshot

2 Answers 2

0

This is likely not the "ideal" approach, but this works for me, and now I can move on to other things. If someone has a better option, I'd love to hear it, thank you.

$base_args = [
    'post_type'   => 'crowdfunding',
    'numberposts' => 30,
    'posts_per_page' => '50',
];

$meta_query = array(
    array(
        'key'        => 'campaign_start_date',
        'compare'    => '<=',
        'value'      => $in_three_days,
    ),
    array(
        'key'        => 'campaign_end_date',
        'compare'    => '>=',
        'value'      => $today,
    ),
);

$args = array(
    'meta_key'      => 'campaign_end_date',
    'orderby'       => 'meta_value_num',
    'order'         => 'ASC',
    'meta_query'    => $meta_query,
);

$crowdfunding_posts = new WP_Query(get_posts(array_merge($base_args, $args)));

usort($crowdfunding_posts->query, function($a, $b) {
    return strcasecmp( 
        $b->campaign_is_featured,
        $a->campaign_is_featured, 
    );
});

And now it's behaving just like I want it to. I can take the little hit for the sort because the page itself is also being cached.

enter image description here

0

Try to name the two arrays you want to use for the orderby. Like this:

$args = array(
    'meta_key'       => 'campaign_end_date',
    'orderby'        => 'meta_value_num',
    'order' => 'ASC',
    'meta_query'  => array(
        'start' => array(
            'key'        => 'campaign_start_date',
            'compare'    => '<=',
            'value'      => $in_three_days,
        ),
        'end' => array(
            'key'        => 'campaign_end_date',
            'compare'    => '>=',
            'value'      => $today,
        ),
    ),
);

After that, you can make an orderby array like so:

 'orderby' => array(
        'start' => 'DESC',
        'end' => 'ASC',
    ),

The final query then looks something like this:

$args = array(
    'meta_key'       => 'campaign_end_date',
    'order' => 'ASC',
    'meta_query'  => array(
        'start' => array(
            'key'        => 'campaign_start_date',
            'compare'    => '<=',
            'value'      => $in_three_days,
        ),
        'end' => array(
            'key'        => 'campaign_end_date',
            'compare'    => '>=',
            'value'      => $today,
        ),
'orderby' => array(
        'start' => 'DESC',
        'end' => 'ASC',
    ),
    ),
);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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