REWORKED APPROACH
Due to this becoming a bit of tameletjie due to styling issues, lets rework everything and look at a different approach
I think what we should do here is to rather shuffle the $posts
array through usort()
to get the posts sorted in the order we want, and then there after we can run the loop normally
Create our query:
<?php
$args = array(
'tax_query' => array(
array(
'taxonomy' => 'post-status',
'field' => 'slug',
'terms' => array ('post-status-published')
)
)
);
$query = new WP_Query( $args );
Now that we have ran our query, we need to get the $posts
property from $query
and sort it. So this part will go below our query: (NOTE: This is completely untested)
if ( $query->have_posts() ) :
// Now we will use usort to sort the posts array
@usort( $query->posts, function ( $a, $b ) // @ hides the bug before PHP 7
{
// Assign sortable values for categories to sort posts by
$array = ['a' => $a, 'b' => $b];
$sort_order_a = '';
$sort_order_b = '';
foreach ( $array as $key=>$p ) {
if ( in_category( 'First', $p ) ) {
${'sort_order_' . $key} = 1;
} elseif ( in_category( 'Second', $p ) ) {
${'sort_order_' . $key} = 2;
} else {
${'sort_order_' . $key} = 3;
}
}
// Now that we have a custom sorting order, lets sort the posts
if ( $sort_order_a !== $sort_order_b ) {
// Make sure about <, change to > to change sort order
return $sort_order_a < $sort_order_b;
} else {
/**
* Sort by date if sorting order is the same,
* again, to change sort order, change > to <
*/
return $a->post_date > $b->post_date;
}
});
// Our posts is now sorted, run the loop normally
// Define our counter to set our columns
$counter = 0;
$midpoint = ceil( $query->post_count / 2 );
while ( $query->have_posts() ) :
$query->the_post();
// set our left div on first post
if ( 0 == $counter ) :
?>
<div id="left">
<?php
endif;
// Close our left div and open the right one on midpoint
if ( ( $counter + 1 ) == $midpoint ) :
<?php
</div>
<div id="right">
<?php
endif;
// Lets output the posts with different styling
if ( in_category( 'First', get_the_ID() ) {
// Apply styling for category First and display title
the_title();
} elseif ( in_category( 'First', get_the_ID() ) {
// Apply styling for category Second and display title
the_title();
} else {
// Apply styling for other posts and display title
the_title();
}
/**
* Lets close the div and bail if we have only one post,
* or if we are on the last post
*/
if ( 1 == $post_count
|| ( $counter + 1 ) == $post_count
) :
?>
</div>
<?php
endif;
// Update our counter
$counter++;
endwhile;
wp_reset_postdata();
endif;
ORIGINAL ANSWER
Your second block of code won't work and beats the whole reason for your previous question. Just a note on that code, you should not be using $wp_query
as a local variable, it is is a reserved global variable which is intenally used in WordPress to hold the main query object. Breaking this global will break a lot of other stuff. What you are doing is what query_posts()
does, that is also why you should never use query posts.
Your issue is that your counter is wrongly updated, thus it wrongly adds your divs. What we need to do is to only update our counder in our conditional statements to prevent posts being double counted and therefor stuufing out layout.
We will only use the first loop and modify that accordingly. The only tricky part will be when to open and close divs
EDIT
Due to the code getting a bit techincal, I scrapped my original idea. We will still use the code in block one, except, it would be much easier to loop through the posts as before and create a new array and finally loop through that array and display the posts.
<?php
$args = array(
'tax_query' => array(
array(
'taxonomy' => 'post-status',
'field' => 'slug',
'terms' => array ('post-status-published')
)
)
);
$query = new WP_Query( $args );
if ( $query->have_posts() ) :
/**
* Get the amount of posts in the loop, this will be used
* to calculate when to open and close our divs
*/
$post_count = $query->post_count;
/**
* Get a midpoint to break the div into left and right
*/
$midpoint = ceil( $post_count / 2 );
$duplicates = [];
$post_titles = [];
while ( $query->have_posts() ) :
$query->the_post();
if ( in_category( 'First' ) ) :
$post_titles[] = apply_filters( 'the_title', get_the_title() );
$duplicates[] = get_the_ID();
endif;
endwhile;
$query->rewind_posts();
while ( $query->have_posts() ) :
$query->the_post();
if ( in_category( 'Second' ) ) :
if ( in_array( get_the_ID(), $duplicates ) )
continue;
$post_titles[] = apply_filters( 'the_title', get_the_title() );
$duplicates[] = get_the_ID();
endif;
endwhile;
$query->rewind_posts();
while ( $query->have_posts() ) :
$query->the_post();
if ( in_array( get_the_ID(), $duplicates ) )
continue;
$post_titles[] = apply_filters( 'the_title', get_the_title() );
endwhile;
wp_reset_postdata();
// Now that we have an array of post titles sorted, lets display them
foreach ( $post_titles as $key=>$post_title ) :
// Open our left div
if ( 0 == $key ) :
?>
<div id="left">
<?php
endif;
// Close our left div and open the right one on midpoint
if ( ( $key + 1 ) == $midpoint ) :
<?php
</div>
<div id="right">
<?php
endif;
// Display the post title
echo $post_title . '</br>';
/**
* Lets close the div and bail if we have only one post,
* or if we are on the last post
*/
if ( 1 == $post_count
|| ( $key + 1 ) == $post_count
) :
?>
</div>
<?php
break;
endif;
endforeach;
endif;
?>
IMPORTANT NOTE:
Al code is untested and can be improved as you see fit. Due to being untested, there might be slight syntax errors or small bugs
Second
, it's whatever is the first post in the queryby default (publish date), minus the posts infirst
andsecond