Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

The below code is taken from sidebar.php where it outputs random posts from multiple categories and excludes the current post from showing up. This works great but how do I alter this loop to exclude all posts from the current pages category? So for example if a post is currently on display and its category is artists, I'd like to exclude all artists posts from being displayed but display all the other categories (stated in the code below).

This is my loop:

<?php
        // First, let's eliminate some DRY,
        // by making an array of our categories
        $random_posts_cat_array = array( 'artists', 'projects', 'people', 'development', 'offsite' );

        // Globalize $post,
        // since we're outside the primary loop
        global $post;
        $post_cats = get_the_category( $post->ID );
        // First array object
        $post_cat = $post_cats[0];
        // Current post category ID
        $post_cat_id = $post_cat->term_id;
        // Current post category slug
        $post_cat_slug = $post_cat->slug;

        // Now, let's find out if we're displaying
        // the category index for one of our categories
        if ( in_array( $post_cat_slug, $random_posts_cat_array ) ) {

            // Set up custom loop args
            $random_posts_query_args = array(
                'posts_per_page' => 3,
                'orderby'       => 'rand',
                'post__not_in'  => array( $post->ID )
            );
            // Add Cat ID to custom loop args
            foreach ( $random_posts_cat_array as $random_post_cat ) {
                if ( $post_cat_slug == $random_post_cat ) {
                    // Add Cat ID
                    $random_posts_query_args['cat'] = $post_cat_id; 
                }
            }

            // Run random posts query
            $random_posts_query = new WP_Query( $random_posts_query_args );

            // Setup random posts query loop
            if ( $random_posts_query->have_posts() ) : while ( $random_posts_query->have_posts() ) : $random_posts_query->the_post();?>

                    <?php foreach( get_the_category() as $cat ) echo '<div class="module ' . $cat->slug . '" data-category="' . $cat->slug . '" >'; ?>

                          <a href="<?php the_permalink()?>" title="<?php the_title(); ?>">
                          <div class="active">
                                <div class="hover"></div>
                                <?php the_post_thumbnail(); ?>
                          </div>

                         <?php
                              $sub_title=get_post_meta($post->ID,'subtitle',true);
                              if($sub_title != '') {
                              echo '<h1>'. get_the_title() .'<span> / '. $sub_title .'</span></h1>';
                              } else {
                              echo '<h1>'. get_the_title() .'</h1>';
                              }
                              ?>

                              <?php
                              // Call in the contents of a custom field called Excerpt and if custom field in admin panel is empty don't display <p> tags otherwise wrap contents in <p> tags
                              $excerpt=get_post_meta($post->ID,'Excerpt',true);
                              if($excerpt != '') {
                              echo '<p>'. $excerpt .'</p>';
                              } else {
                              echo ' ';
                              }
                              ?>
                              <p class="date"><?php the_time('YdmHi') ?></p>
                         </a>
                    </div>

           <?php endwhile; endif;

            // Be kind; rewind
            wp_reset_postdata();

        } else { // display nothing ?>


        <?php }?>
share|improve this question

1 Answer 1

up vote 1 down vote accepted

This one is even more simple. Refer to the WP_Query() category parameters. I think you will want to use 'category__not_in'.

foreach ( $random_posts_cat_array as $random_post_cat ) {
    if ( $post_cat_slug == $random_post_cat ) {
        // No posts from this category!
        $random_posts_query_args['category__not_in'] = $post_cat_id;
    }
}

Edit

So for example if a post is currently on display and its category is artists, I'd like to exclude all artists posts from being displayed but display all the other categories (stated in the code below).

Okay, so this is actually a bit different, and I think you'd want to use 'category__in' instead of 'category__not_in':

// Array to hold categories to include
$cats_to_include = array();

// Loop through category slugs, and
// add their IDs to this array
foreach ( $random_posts_cats_array as $random_post_cat ) {
    $random_post_cat_obj = get_category_by_slug( $random_post_cat );
    $cats_to_include[] = $random_post_cat_obj->term_id;
}

// unset current cat
// call this after you define $post_cat_id
if ( in_array( $post_cat_id, $cats_to_include ) ) {
    unset( $cats_to_include[$post_cat_id] );
}

// Now build custom query args
$random_posts_query_args['category__in'] = $cats_to_include;

Edit 2

Complete code (cleaned up a bit, for legibility):

<?php
// First, let's eliminate some DRY,
// by making an array of our categories
$random_posts_cat_array = array( 'artists', 'projects', 'people', 'development', 'offsite' );

// Globalize $post,
// since we're outside the primary loop
global $post;
$post_cats = get_the_category( $post->ID );
// First array object
$post_cat = $post_cats[0];
// Current post category ID
$post_cat_id = $post_cat->term_id;
// Current post category slug
$post_cat_slug = $post_cat->slug;

// Now, let's find out if we're displaying
// the category index for one of our categories
if ( in_array( $post_cat_slug, $random_posts_cat_array ) ) {

   // Set up custom loop args
    $random_posts_query_args = array(
        'posts_per_page' => 3,
        'orderby'       => 'rand',
        'post__not_in'  => array( $post->ID )
    );

    // Array to hold categories to include
    $cats_to_include = array();

    // Loop through category slugs, and
    // add their IDs to this array
    foreach ( $random_posts_cats_array as $random_post_cat ) {
        $random_post_cat_obj = get_category_by_slug( $random_post_cat );
        $cats_to_include[] = $random_post_cat_obj->term_id;
    }

    // unset current cat
    // call this after you define $post_cat_id
    if ( in_array( $post_cat_id, $cats_to_include ) ) {
        unset( $cats_to_include[$post_cat_id] );
    }

    // Now build custom query args
    $random_posts_query_args['category__in'] = $cats_to_include;

    // Run random posts query
    $random_posts_query = new WP_Query( $random_posts_query_args );

    // Setup random posts query loop
    if ( $random_posts_query->have_posts() ) : while ( $random_posts_query->have_posts() ) : $random_posts_query->the_post();

        foreach( get_the_category() as $cat ) {
            echo '<div class="module ' . $cat->slug . '" data-category="' . $cat->slug . '" >';
            ?>

            <a href="<?php the_permalink()?>" title="<?php the_title(); ?>">
                <div class="active">
                    <div class="hover"></div>
                    <?php the_post_thumbnail(); ?>
                </div>

                <?php
                $sub_title=get_post_meta($post->ID,'subtitle',true);
                if($sub_title != '') {
                    echo '<h1>'. get_the_title() .'<span> / '. $sub_title .'</span></h1>';
                } else {
                    echo '<h1>'. get_the_title() .'</h1>';
                }

                // Call in the contents of a custom field called Excerpt,
                // and if custom field in admin panel is empty don't 
                // display <p> tags otherwise wrap contents in <p> tags
                $excerpt=get_post_meta($post->ID,'Excerpt',true);
                if($excerpt != '') {
                    echo '<p>'. $excerpt .'</p>';
                } else {
                    echo ' ';
                }
                ?>
                <p class="date"><?php the_time('YdmHi') ?></p>
            </a>
        </div>

        <?php 
    endwhile; endif;

    // Be kind; rewind
    wp_reset_postdata();

} 
?>

Edit 3

Okay, here's why the Cat ID isn't getting removed from the category__in array:

if ( in_array( $post_cat_id, $cats_to_include ) ) {
    unset( $cats_to_include[$post_cat_id] );
}

But here's the array structure:

["category__in"]=> array(5) { 
    [0]=> int(1) 
    [1]=> int(6) 
    [2]=> int(3) 
    [3]=> int(5) 
    [4]=> int(7) 
}

See the problem? We're looking at the key instead of at the value. So, try this instead:

foreach ( $cats_to_include as $cat_key => $cat_value ) {
    if ( $cat_value == $post_cat_id ) {
        unset( $cats_to_include[$cat_key] );
    }
}

Try that, and report back the var_dump() again, so we can see if $cats_to_include now gets updated properly.

share|improve this answer
    
I think this is doing the job but for some reason its not outputting 3 posts it seems to be outputting 19 instead. Any ideas? –  egr103 May 31 '12 at 18:20
    
You had 'post_per_page', propagated from my typo in the other question. –  Chip Bennett May 31 '12 at 20:00
    
I thought it was that initially but after correcting it, I still got all those posts appear. Not sure whats causing it. –  egr103 May 31 '12 at 20:09
    
I've updated my answer, based on your updated question. –  Chip Bennett May 31 '12 at 20:20
    
With regard to my original loop, where do I paste this code? –  egr103 May 31 '12 at 20:48

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.