Support » Fixing WordPress » Sticky Posts in WP_Query

  • Arhhh, this is driving me nuts so any help would be really appreciated. In a custom page template I am trying to display a list of posts from a category with those posts that have sticky status to be first in the list of posts and then all other posts listed below but I can’t seem to get it to work. It either displays all posts, ignoring the sticky status or only shows the sticky posts.

    Here’s the query:

    <?php
      $temp = $wp_query;
      $wp_query = new WP_Query( array( 'posts_per_page' => '10', 'paged' => $paged, 'cat' => 275, 'post__in' => get_option('sticky_posts')));
      while ($wp_query->have_posts()) : $wp_query->the_post();
    ?>
Viewing 4 replies - 1 through 4 (of 4 total)
  • Moderator keesiemeijer

    (@keesiemeijer)

    Sticky posts only show on top of the home page. To achieve the same on a category page you have to use multiple loops. The first for all your sticky posts and the second with all other posts but with all sticky posts excluded.

    something like this:

    <?php
    	// show all sticky posts on the first page
    	if(!is_paged()) {
    	$args = array(
    	  'posts_per_page' => -1,
    	  'cat'            => 275,
    	  'post__in'       => get_option('sticky_posts')
    	);
    
    	$my_query1 = new WP_Query($args);
    	while ($my_query1->have_posts()) : $my_query1->the_post();
    	// rest of loop
    	endwhile;
    	wp_reset_postdata();
    	} // !is_paged 
    
    	// second loop (paginated)
    		$args = array(
    	  'posts_per_page' => '10',
    	  'paged'          => $paged,
    	  'cat'            => 275,
    	  'post__not_in' => get_option( 'sticky_posts' )
    	);
    
    	$my_query2 = new WP_Query($args);
    	while ($my_query2->have_posts()) : $my_query2->the_post();
    	// rest of loop
    	endwhile;
    	// pagination functions here
    	wp_reset_postdata();
    ?>

    Thread Starter greencode

    (@greencode)

    Thanks for this. I’ve tried using this but what seems to happen is the sticky post then also shows up in the second loop. here’s my code:

    <?php
      $temp = $wp_query;
      $wp_query = new WP_Query( array( 'posts_per_page' => '-1', 'paged' => $paged, 'cat' => 275, 'post__in' => get_option('sticky_posts')));
      while ($wp_query->have_posts()) : $wp_query->the_post();
    ?>
    <a href="<?php the_permalink() ?>"><?php the_title() ?></a>
    <?php endwhile;?>
    <?php wp_reset_postdata(); ?>
    <?php
      $temp = $wp_query;
      global $more; $more = 0;
      $wp_query = new WP_Query( array( 'posts_per_page' => '10', 'ignore_sticky_posts' => 1, 'post__not_in' => $sticky, 'paged' => $paged, 'cat' => 275));
      while ($wp_query->have_posts()) : $wp_query->the_post();
    ?>
    <a href="<?php the_permalink() ?>"><?php the_title() ?></a>
    <?php endwhile;?>
    <?php wp_reset_postdata(); ?>
    <div class="grid_9">
    <?php if(function_exists('wp_pagenavi')) { wp_pagenavi(); } ?>

    Greencode, your second query should be:

    $wp_query = new WP_Query( array( 'posts_per_page' => '10', 'ignore_sticky_posts' => 1, 'post__not_in' => get_option('sticky_posts'), 'paged' => $paged, 'cat' => 275));

    not

    $wp_query = new WP_Query( array( 'posts_per_page' => '10', 'ignore_sticky_posts' => 1, 'post__not_in' => $sticky, 'paged' => $paged, 'cat' => 275));

    Nowhere in your example, do you set the $sticky variable.

    Here is an alternative method that I used on another site. The gist is to always force the sticky on top, which is kind of what it’s supposed to do, but the sticky post was no longer a “recent” post, and it was not getting picked up by the query. This may not be the best solution, but it worked for me (I ONLY have access to this template file, and not the WP core files). $categories was set previously in the program for a specific one….

    $recent_posts = new WP_Query(array(
    				'showposts' => $posts,
    				'post_type' => 'post',
    				'ignore_sticky_posts' => 'false',
    				'post__not_in' => get_option('sticky_posts'),
    				'cat' => $categories,
    			));
    
    			$recent_sticky_posts = new WP_Query(array(
    				'showposts' => $posts,
    				'post_type' => 'post',
    				'ignore_sticky_posts' => 'false',
    				'post__in' => get_option('sticky_posts'),
    				'cat' => $categories,
    			));
    
    			$my_regposts = array();
    			$my_stickyposts = array();
    
    			foreach($recent_sticky_posts->posts as $my_post) {
    				array_push($my_stickyposts,$my_post);
    			}
    
    			foreach($recent_posts->posts as $my_post) {
    				array_push($my_regposts,$my_post);
    			}
    
    			// clear out the original query and push on the regular and sticky posts
    			$recent_posts->posts = array();
    
    			// sticky posts first
    			foreach($my_stickyposts as $my_stickypost) {
    				array_push($recent_posts->posts,$my_stickypost);
    			}
    			// regular posts next
    			foreach($my_regposts as $my_regpost) {
    				array_push($recent_posts->posts,$my_regpost);
    			}

    What this bit of code replaced was just a normal get of recent posts. The regular version was not getting the sticky ones (because they were no longer recent)

Viewing 4 replies - 1 through 4 (of 4 total)
  • The topic ‘Sticky Posts in WP_Query’ is closed to new replies.