I have a modified theme that displays CPT posts. I am creating a slider that will cycle through all the sticky posts and display them at the top of the page. So far so good.

The problem. When I have less than 5 posts in a given category. The slider code doesn't display posts properly (they shrink in size, repeat, all kinds of weird stuff). Now before you suggest I try a different slider, please note that this one is hardcoded into the theme. I could comment it out, drop in a new code for another slider, but that's just one more plugin/theme element to maintain. I'd like to see if my logic can be fixed.

What I need. I'm looking for an if/else statement that lets me deliver 2 different loops, one where I can pass args of one type, and another to pass the second set of args (which is to pull from all other categories if that specific category has less than 5 posts).

Here is the code I was using - ALMOST SUCCESSFULLY (see below code for more).

<div class="slider">

<ul>
<?php
$term = get_term_by('slug', get_query_var('term'), get_query_var('taxonomy'));
$sticky = get_option('sticky_posts');
    $args_cat_only = array (
        'my_cat' => $term->slug,
        'posts_per_page' => -1,
        'post__in' => $sticky,
        'post_type' => MYCPT_POST_TYPE,
        'post_status' => 'publish',
        'orderby' => 'rand',
    );
$cat_only_query = new WP_Query( $args_cat_only );

if ( $cat_only_query->have_posts() ) {
    while ( $cat_only_query->have_posts() ) {
        $cat_only_query->the_post(); ?>

        <li>
        // items from category only
        </li>

   <?php  } wp_reset_postdata(); 

if( count($cat_only_query->posts) <= 4 ) { 

    $args_all_cats = array ( //Args to pull from all categories
        'orderby' => 'rand',
        'posts_per_page' => -1,
        //'my_cat' => $term->slug,
        'post__in' => $sticky,
        'post_type' => MYCPT_POST_TYPE,
        'post_status' => 'publish'
    );

    $cat_query_all = new WP_Query( $args_all_cats );

    if( $cat_query_all->have_posts() ) {
        while( $cat_query_all->have_posts() ) {
            $cat_query_all->the_post(); ?>

        <li>
        // items from ALL categories
        </li>

   <?php } wp_reset_postdata();
            }
        }
    }
?>    
</ul>

This code works to query all CPT posts, specific to the category we're in, and return sticky posts UNLESS there are less than 5 (4 or less). In that case, it grabs posts from ALL categories. The problem is that because have_posts() returns true ONLY if there ARE posts, my logic is broken when there are ZERO posts from the loop.

I could add yet another elseif/else statement and run through a scenario where there are NO posts, but I'd rather not do that (unless that's the only way). Can I modify my 2nd query somehow, so so that when it does the count check, it says "if there are less than 5, OR there are zero, do foo"?

有帮助吗?

解决方案

I would start by creating an array to put your posts into, to create a counting system of some kind. Dump your list item output into that array, count it, and use the remaining count to call your second query.

<?php
$term = get_term_by('slug', get_query_var('term'), get_query_var('taxonomy'));
$sticky = get_option('sticky_posts');

// Moved the base arguments into one array
$base_args = array( 
    'posts_per_page' => 5,  // Changed to 5, because that's the amount you need
    'post_type' => MYCPT_POST_TYPE,
    'orderby' => 'rand'
    'post__in' => $sticky,
);

// Merge your base arguments and cat only arguments
$args_cat_only = array_merge( $base_args, array (
    'my_cat' => $term->slug,
) );

$cat_only_query = new WP_Query( $args_cat_only );

if ( $cat_only_query->have_posts() ) {
    while ( $cat_only_query->have_posts() ) { $cat_only_query->the_post();
        // Start an Output Buffer
        ob_start();
        ?>

        <li>
        // items from category only
        </li>

        <?php
        // Dump output into list item array
        $list_items[] = ob_get_clean();
    }
    wp_reset_postdata();
}

if ( count( $list_items ) < 5 ) {
     // Find out how many posts you need
     $post_need = 5 - count( $list_items );

     // Change base args posts_per_page to only call the amount of posts you need
     $base_args['posts_per_page'] = $post_need;

     // Run the new query based on base arguments
     $fill_in_query = new WP_Query( $base_args );

    if ( $fill_in_query->have_posts() ) {
        while ( $fill_in_query->have_posts() ) { $fill_in_query->the_post();
            // Start an Output Buffer
            ob_start();
            ?>

            <li>
            // items from category only
            </li>

            <?php
            // Dump output into list item array
            $list_items[] = ob_get_clean();
        }
        wp_reset_postdata();
    }
}
?>

<div class="slider">
<ul>
     <?php echo implode( '', $list_items ); // Print your list items ?>
</ul>
</div>

The only problem now is that your random pull in your second query could technically pull a random one from the first query.

I didn't test any of this code, please let me know if you have any questions.

许可以下: CC-BY-SA归因
scroll top