まず、WP_Query を使用する場合、'showposts' は 'posts_per_page' に置き換えられました。私はあなたのコードでそれを修正しました。また、ループ内では $single_cat_post->ID の代わりに $post->ID を使用できるはずです。
私は2つのループを使用します。パラメータを設定し、最初のループにメタ値をチェックする条件を含め、クエリをリセットしてから、別のループを実行し、メタ値をチェックして存在する場合は何も出力しない条件を含めます。
最初のクエリでは、最初のループで返される投稿の数を確認するチェックを追加しました。次に、その値 (4 を引いた値) を使用して、2 番目のループで posts_per_page に使用する変数を計算しました。次に、結果が 0 より大きい場合にのみループを実行する条件を追加しました。
これはテストされていませんが、動作するか、少なくとも正しい道に進むはずです!
<?php
$args = array(
'posts_per_page' => 4,
'meta_key' => 'soy_featured_post',
'cat' => $instance["cat"],
'orderby' => 'date',
'order' => 'ASC'
);
$special_post_query = new WP_Query( $args );
$special_posts_found = $special_post_query->found_posts;
if ($special_post_query->have_posts()) :
while( $special_post_query->have_posts() ) : $special_post_query->the_post();
// POST WITH META VALUE OUTPUT
the_title();
endwhile;
endif;
wp_reset_query();
$second_loop_posts_per_page = 4 - $special_posts_found;
if ($second_loop_posts_per_page > 0) {
$args = array(
'posts_per_page' => $second_loop_posts_per_page,
'cat' => $instance["cat"],
'orderby' => 'date',
'order' => 'ASC'
);
if ($special_post_query->have_posts() ) :
while( $special_post_query->have_posts() ) : $special_post_query->the_post();
// Condition to test for NO meta value
if (get_post_meta($post->ID, 'soy_featured_post', true) == null) {
// CODE
the_title();
} else {
// Don't print anything because the meta value exists
}
endwhile;
endif;
wp_reset_query();
} ?>