What about an approach like this:
$first_category_args = array(
// category id
'cat' => 123,
// get all from cat
'posts_per_page' => -1,
// don't prepend sticky
'ignore_sticky_posts' => 1,
// only return ids
'fields' => 'ids'
);
// array of ids
$first_category_query = new WP_Query(
$first_category_args
);
$first_category_ids = $first_category_query->posts;
$second_category_args = array(
// category id
'cat' => 456,
// get all from cat
'posts_per_page' => -1,
// don't prepend sticky
'ignore_sticky_posts' => 1,
// only return ids
'fields' => 'ids'
);
// array of ids
$second_category_query = new WP_Query(
$second_category_args
);
$second_category_ids = $second_category_query->posts;
// count
$first_category_ids_count = count( $first_category_ids );
$second_category_ids_count = count( $second_category_ids );
// set count to the greater one
if ( $first_category_ids_count > $second_category_ids_count ) {
$count = $first_category_ids_count;
} else {
$count = $second_category_ids_count;
}
$combined_alternating_category_ids = array();
// create combined alternating array of ids
for ( $c = 0; $c < $count; $c++ ) {
if ( isset( $first_category_ids[ $c ] ) ) {
$combined_alternating_category_ids[] = $first_category_ids[ $c ];
}
if ( isset( $second_category_ids[ $c ] ) ) {
$combined_alternating_category_ids[] = $second_category_ids[ $c ];
}
}
// now do a query with the combined result
$combined_category_args = array(
// get post by created alternating ids array
'post__in' => $combined_alternating_category_ids,
// we're ordering by the order the ids have in the array
'orderby' => 'post__in'
);
$combined_query = new WP_Query(
$combined_category_args
);
// proceed with a loop
if ( $combined_query->have_posts() ) {
while ( $combined_query->have_posts() ) {
$combined_query->the_post();
// show post code
}
} else {
// no post code
}
wp_reset_postdata();
Just as an idea, haven’t tested this, gave it a quick test, does work as expected.
To alter the main query you can do:
function wpse163419_alternate_order_array() {
$first_category_args = array(
// category id
'cat' => 1,
// get all from cat
'posts_per_page' => -1,
// only return ids
'fields' => 'ids'
);
// array of ids
$first_category_query = new WP_Query(
$first_category_args
);
$first_category_ids = $first_category_query->posts;
$second_category_args = array(
// category id
'cat' => 3,
// get all from cat
'posts_per_page' => -1,
// only return ids
'fields' => 'ids'
);
// array of ids
$second_category_query = new WP_Query(
$second_category_args
);
$second_category_ids = $second_category_query->posts;
// count
$first_category_ids_count = count( $first_category_ids );
$second_category_ids_count = count( $second_category_ids );
// set count to the greater one
if ( $first_category_ids_count > $second_category_ids_count ) {
$count = $first_category_ids_count;
} else {
$count = $second_category_ids_count;
}
$combined_alternating_category_ids = array();
// create combined alternating array of ids
for ( $c = 0; $c < $count; $c++ ) {
if ( isset( $first_category_ids[ $c ] ) ) {
$combined_alternating_category_ids[] = $first_category_ids[ $c ];
}
if ( isset( $second_category_ids[ $c ] ) ) {
$combined_alternating_category_ids[] = $second_category_ids[ $c ];
}
}
return $combined_alternating_category_ids;
}
add_action( 'pre_get_posts', 'wpse163419_cat_alternate_order' );
function wpse163419_cat_alternate_order( $query ) {
// avoid infinite loop
remove_action( 'pre_get_posts', __FUNCTION__ );
// get ids
$combined_alternating_category_ids = wpse163419_alternate_order_array();
// set query parameter
if ( ! is_admin() && $query->is_main_query() ) {
$query->set( 'post__in', $combined_alternating_category_ids );
$query->set( 'orderby', 'post__in' );
$query->set( 'posts_per_page', '-1' );
}
}