I try to change the main loop in such a way: I have a meta key for displaying featured items, that should be shown only on the home page of the a blog. I pull them in a code separate from the main loop, something like -

$leading = get_posts('showposts=5&meta_key=_pull_leading3&meta_value=on');      
    foreach ($leading as $post) : 
        //some code to show posts data

Then in the main loop, I want to show only posts that are not assigned as featured, so I alter the main loop with query_posts :


Till here everything is ok. But, I also want that if I go to any other older pages, I will get the featured posts again, if they should be there naturally via the regular order. In this case, since I use the meta values, I don't get them. If I try something like this -

if (is_home() && $paged == '0') {  //$paged value is 0 on 1st page and not 1 !          
      else {

Then on page #2 I do get the posts as needed, but i is repeating part of the posts that were on page #1 (home page) (Since in homepage loop I showed only posts that are not featured, so since that part of the posts already shown there, and now should be excluded from page #2).

How can I alter the main loop in a way that the main page will show the posts that are not featured, and that the other $paged pages will show posts in a native way, no matter if they are featured or not, and without repeating posts from the previous page?

I really hope I succeed to explain my issue...

Many thanks, Maor

  • So, when $paged > 0, you want to exclude posts were in the home page loop? The way you have it set up, it looks like you would have to recreate the home page loop, get those page ids and exclude those posts by passing a post__not_in parameter. But I have to question your general structure. Is there a reason you can't use the sticky option to structure your queries better? Jan 28, 2011 at 22:09
  • I can't use sticky in this case, since I handle this meta_key to show it as an additional column in the edit posts admin panel and I also use some Ajax to let the admin change the status from featured / not featured and so on. The meta_value is being properly changed in the db with Ajax, and I want to find a way to use this meta key to implement that. I don't want to use the sticky in here. I'm going to test your solution you suggested in the answer below Jan 28, 2011 at 23:50

2 Answers 2


I think this will do what you want. But I still wonder whether sticky posts wouldn't have been better...

if (is_home() && $paged == '0') {  //$paged value is 0 on 1st page and not 1 !          
      else {
        // recreate the home page "loop" to figure out which posts to exclude
        $excluded = array_map(
            create_function('$post', 'return $post->ID;' ),
        query_posts( array(
            'posts_per_page' => 7,
            'paged' => $paged-1, // since we already excluded the first page
            'post__not_in' => $excluded) );          
  • I tested it and it appears it getting close to what is needed here. The problem now is now as this: suppose I chose as "featured" posts to be posts #3, 10, 11. So, in the main loop in the homepage (which shows all posts besides the featured) I get posts #1,2,4,5,6,7,8. Then, the 2nd page shows me 3,9,10,11,12,13,14. This is better than what I got before, since now I have the posts naturally there, but the post #3 shouldn't appear on page 2, since it's not in place. How can I avoid that ? Jan 28, 2011 at 23:54
  • A 2ns issue with this (but less important for now), is since we use parameter $paged-1, so plugins like wp_page_navi don't show the correct number of page , and when on page 2 it shows number 1 etc. Anyway, this is less important now, I might show only links to prev/next pages and not for page numbers or so. Jan 29, 2011 at 0:00
  • why not use the "Offset Parameter" like 'offset' => ($paged * $posts_per_page)?
    – Bainternet
    Jan 29, 2011 at 8:37
  • Since the featured items are dynamic. Offset removes the first X posts from the query, but featured item can be any item in the entire blog, not necessarily the last 3 new ones Jan 29, 2011 at 13:07
  • @goldenapples, please see below I added some code that might complete your answer. Thanks Jan 29, 2011 at 13:25

@goldenapples, as I commented earlier, your code gave a good start but gave on prev pages some unneeded posts that were featured. I added a function to filter the posts_where, and it calculates the date of the last post in the first page and filter to bring posts that are earlier than it. It appears that it does it, but I'm not completely sure there are not bugs in that. Could you take a look in this function and say your opinion:

add_filter( 'posts_where' , 'tc_special_posts_where' );
function tc_special_posts_where( $where ) { 
    global $wpdb, $paged, $post;
    $paged = get_query_var('paged');
    $g = get_posts('numberposts=7&meta_key=_pull_leading3&meta_value=off&paged=0');
    foreach ($g as $p) { $i = $p->post_date; } 

    if (is_home() && $paged > 0) {
     $where .= " AND post_date < '" . $i . "'";
return $where; }

More than that, since we changed the $paged, so the function next_posts_link() in such case is showing the current page as the next page, so I had to do some replacements -

$x = preg_match('/(\d){1,}/', $uri, $matches); //catch the digit of page number     
$nextlink = get_next_posts_link('Next Page »', 0);
if ($matches) {   //on the first page not needed to replace, only from page 2 and on
    $nextlink = preg_replace('/(\d){1,}/e', '"$1"+1'  ,$nextlink);  
<span class="alignleft"><?php echo $nextlink;?></span>
  • Actually this looks like it should work. I wouldn't try and use regex to capture the paged query var, though... just store it in a variable before you manipulate the query and refer to that later for your next link. (Another suggestion, if you reset that query variable to its original value after running query_posts, will your page nav functions work properly? Just a thought, but might be easier than the hacks you have going on.) Jan 29, 2011 at 19:52

Your Answer

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

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