4

I have a custom post type for a group of people (employees). At first, I needed to display 7 random employees. That was easy

<?php 
    $args = array(
        'post_type' => 'employees',
        'orderby' => 'rand',
        'posts_per_page' => 7,
    );
    $query = new WP_Query($args);
    while ( $query->have_posts() ) { $query->the_post();
        //do stuff
    <?php endif;
    } wp_reset_postdata(); 

?>

But now I've been asked to make sure at least one of the seven is always a woman. The man to woman ratio at the company is 4 to 1.

I've set a checkbox that I can test for:

<?php if( in_array( 'yes', get_field('is_female') ) ){
 // this is a female
}

I need help putting it all together. I assume I need to keep track if any of the posts are displayed are women. Once I get to the 7th position if a woman isn't listed, I need to keep iterating until I find one.

Any suggestions?

2

I think the best way here would be to run three separate loops here (you can also do two loops, but then you need to get full posts in the men and women queries, combine them and shuffle them), the first two will be used to get 5 men and the second loop will get 2 women. You can adjust this as necessary. The third loop will use the info from the first two loops to get the full posts.

Here I accept that you are using a custom field which has two separate values, one for men and one for women. Also, I accept that you don't need to paginate this query.

You can try something like this

/*
 * First query to get 5 men. Only get post ID's to increase performance
 */
$args1 = array(
    'posts_per_page'   => 5,
    'orderby'          => 'rand',
    'suppress_filters' => true,
    'no_found_rows'    => true,
    'fields'           => 'ids',
    'meta_query'       => array(
        array(
            'key'   => 'custom-field-name',
            'value' => 'value-for-men',
        )
    )
);
$men = new WP_Query( $args1 );

/*
 * Second query to get 2 women. Only get post ID's to increase performance
 */
$args2 = array(
    'posts_per_page'   => 2,
    'orderby'          => 'rand',
    'suppress_filters' => true,
    'no_found_rows'    => true,
    'fields'           => 'ids',
    'meta_query'       => array(
        array(
            'key'   => 'custom-field-name',
            'value' => 'value-for-women',
        )
    )
);
$women = new WP_Query( $args2 );

/*
 * Merge the post id's from the two queries
 */
$merged_ids = array_merge( $women->posts, $men->posts );

/*
 * Use the merged array of post id's to get the complete posts. Use 'orderby' => 'post__in'
 * to keep shuffled order of the posts that will be returned
 */ 
$args3 = array( 
    'post__in' => shuffle( $merged_ids ),
    'orderby' => 'post__in'
);
$merged_queries = new WP_Query( $args3 ); 

?><pre><?php var_dump($merged_queries->posts); ?></pre><?php    
  • Thank you! This was exactly the direction I needed. I made a few adjustments. – Christina Mar 24 '15 at 2:26
  • Glad you were able to solve this. My code is only a base you can work from. Great that you pulled it apart and modified as needed. Good luck on your project. :-) – Pieter Goosen Mar 24 '15 at 6:14
2

I made a few adjustments. Once I created my two arrays, I combined them this way

$merged_queries->posts = array_merge( $women->posts, $men->posts );
shuffle($merged_queries->posts);
$merged_queries->post_count = $women->post_count + $men->post_count;

while ( $merged_queries->have_posts() ) { $merged_queries->the_post();
// do stuff

It seems a little slow, so I might have some redundancy or inefficiency, but it is giving me the results I'd hoped for.

  • There is not much you can do to optimize random queries. You cannot cache them or store them in a transient because ofcouse they are random results that changes with each query. The impact on performance quering these 7 posts, whether or not you run two or three queries, will not be that significant. Yes, it will be slower, but it will be milliseconds, nothing to break your head about :-) – Pieter Goosen Mar 24 '15 at 6:20
  • Thank you again. This was my first time using this forum and you've made the experience a wonderful one. I'll try to pay it forward by finding a question I can answer :) – Christina Mar 24 '15 at 12:24
  • It is my pleasure. For your first time your question was well formatted, and most importantly, it showed effort and research and you did make that extra effort to help yourself. In my books, always +1. It is always a pleasure trying to help such users. Enjoy :-) – Pieter Goosen Mar 24 '15 at 12:30

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.