WP_Query: Trouble with arguments "cat" and "category_name"

Hi there,
Thanks for stopping by.

I'm having trouble displaying posts in specific categories.
My query looks like this:

<?php $loop = new WP_Query(
   array( 'cat' => '42',
      'posts_per_page' => '5',
      'order' => 'DESC'
); ?>

I've created a category called "Featured" (slug: "featured"), for featured posts on the home page.
I can get any other posts to display, as long as I'm not choosing specific categories.
I've always had trouble with the arguments "cat" and "category_name", as well as "category__in". What am I doing wrong here?

  • Nithin

    Hi SixTsevN,

    Hope you are doing good today. :slight_smile:

    I've always had trouble with the arguments "cat" and "category_name", as well as "category__in". What am I doing wrong here?

    What you meant by "trouble"? Isn't the post getting displayed? The query loop what you have pasted above looks correct, and it should have displayed posts only specific to to category 42. How are you outputting the content?

    Could you please share the entire code, so that we could have a better idea regarding this? In general the code would be something like:

    $query = new WP_Query( array( 'cat' => '53', 'posts_per_page' => 5, 'order' => 'DESC' ));
    // Check that we have query results.
    if ( $query->have_posts() ) {
        // Start looping over the query results.
        while ( $query->have_posts() ) {
            // Contents of the queried post results go here.
    	//get_template_part( 'content', get_post_format() );
    // Restore original post data.

    You might find the following article helpful:

    Please let us know how that goes, have a nice day. :slight_smile:

    Best Regards,

    • SixTsevN

      Hi Nithin,
      Yes I am having a fairly good day. I hope yours is just as good.

      Pardon my lack of information in my initial post. I thought that perhaps my query had a syntax error, but now I'm even more stumped. I was reading the article you linked me to, earlier in the day; before opening this support ticket. I don't really understand why the query is not working. When I leave out the "cat" and "category_name" filters, the non-featured posts show up instead. So I just don't understand what could be wrong.

      	The template part that displays the featured content of blog.
      <!-- FEATURED
      ================================================== -->
      <header id="featured-header">
      	<h2>Featured articles</h2>
      <section id="timeline">
      	<div class="container-fluid clearfix">
      		<div id="featured" class="row">
      			<!-- Get the featured posts -->
      			<?php $loop = new WP_Query(
      				array( 'cat' => '42',
      					   'posts_per_page' => '5',
      					   'order' => 'DESC' ) ); 
      			$strSecondary = "secondary";
      			$strTertiary = "tertiary";
      			$current = "";
      			for( $i = 0; $i < 3; $i++ ) : $loop->the_post();
      				if( $i === 0 ) : ?>
      					<div id="primary" class="col-sm-6 featured">
      					<div class="post-excerpt">
      				<?php else : ?>
      					<!-- Insert Secondary and Tertiary Columns -->
      					<div id="<?php if( $i === 1 ) : $current = $strSecondary; else : $current = $strTertiary; endif; echo $current; ?>" class="col-sm-3 featured">
      					<!-- Insert One and Two Excerpts -->
      					<div id="<?php echo $current . '-one'; ?>" class="post-excerpt">			
      				<?php endif;
      				// nIterations through do..while loop
      				$j = 0;
      				do {
      					if ( $i !== 0 && $j === 1 ) : ?>
      						<div id="<?php echo $current . '-two'; ?>" class="post-excerpt">
      					<?php endif; 
      					$post_link = "blog";
      					$post_img = "";
      					$post_title = "Featured Post";
      					$post_cat_class ="uncategorized-bg-transp";
      					$post_subtitle = "More Coming Soon";
      					if ( $loop->have_posts() ) {
      						$cat = end(get_the_category())->name;
      						if ( $cat !== "Uncategorized" ) {
      							$post_cat_class = strtolower($cat . '-bg-transp');
      						$post_href = get_permalink();
      						$post_img = get_field( 'post_img' )['id'];
      						$post_title = get_the_title();
      						$post_subtitle = get_field( 'post_subtitle' );
      					if ($post_img === "" || !isset( $post_img ) ) {
      						$post_img = "163";
      					} ?>
      					<a href="<?php echo $post_href; ?>" class="inner">
      					<figure style="background: url(<?php echo wp_get_attachment_image_src($post_img, 'large')[0]; ?>) no-repeat center"></figure>
      					<footer class="<?php echo $post_cat_class; ?>">
      					<h2><?php echo $post_title; ?></h2>
      					<p><?php echo $post_subtitle; ?></p>
      					<?php if ( $i !== 0 && $j === 0 ) :
      						echo '</div><!-- .post-excerpt -->';
      				} while ( $i !== 0 && $j < 2 ); ?>
      				</div><!-- .post-excerpt -->
      				</div><!-- .featured -->
      			<?php endfor; wp_reset_query(); ?>
      		</div><!-- .row -->
      	</div><!-- .container -->

      Above is my template part for the featured section of the page. It's a bit complex, because I have to account for different sized containers and multiple columns, that are stacked within those containers; that also have different id's and classes. I assure you the markup and the logic is sound, because when I remove the query arguments for the categories, all of the blog posts are displayed.

      You'll also notice that, the loops continue even when there is no content. This is to preserve the layout of the page and fill the containers with default content when there are no posts; rather than displaying a "no-posts" message.

  • SixTsevN

    Okay... I found the issue.
    $wp_query->have_posts() will only work if you are not at the end of the list of posts. If you have one post that fits your argument "cat", stepping into the list with "$wp_query->the_post()", will bring you to the first post in the list and also the last. Thereafter, testing "$wp_query->have_posts()" will return false. Pretty poor programming if you ask me.

    To overcome this I had to pass this statement:
    if ( get_the_title !== "" )

    Alternatively, you can look here and see why this occurs and I think the function shows how to overcome this flaw in "have_posts()":

    Excerpt from Wordpress Codex

    Calling this function within the loop will cause an infinite loop. For example, see the following code:

    while ( have_posts() ): the_post();
            // Display post
            if ( have_posts() ): // If this is the last post, the loop will start over
                    // Do something if this isn't the last post

    If you want to check if there are more posts in the current loop without this unfortunate side effect, you can use this function.

    function more_posts() {
      global $wp_query;
      return $wp_query->current_post + 1 < $wp_query->post_count;


Thank NAME, for their help.

Let NAME know exactly why they deserved these points.

Gift a custom amount of points.