0

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 }?>

1 Answer 1

1

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.

33
  • 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, 2012 at 18:20
  • You had 'post_per_page', propagated from my typo in the other question. May 31, 2012 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, 2012 at 20:09
  • I've updated my answer, based on your updated question. May 31, 2012 at 20:20
  • With regard to my original loop, where do I paste this code?
    – egr103
    May 31, 2012 at 20:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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