0

I'm new to Wordpress and PHP and I've been battling with this for a while now. What I have for the moment is 2 loops.

I want to first loop to only ever show 1 post: either a sticky post, or the latest post if there are no sticky posts.

The second loop should show all other recent posts, like a basic blog, except any posts which are stickied or the recent post which appears in the first loop.

Example: enter image description here

What I have:

My code shows the latest post in the first loop and other posts in the second loop.

The problem:

When I make a sticky post, it appears in the first loop along with the latest post (I only want the sticky post to appear here in this situation and not both), and it also appears at the top of the second loop.

Here it is in action

I've managed to get this far but I can't seem to finish it.

UPDATED

<div id="main" class="site-main">
    <div id="primary" class="content-area">
        <div id="content" class="site-content" role="main">
            <div>
            <?php 

            $args = array(
                'posts_per_page' => 1,
                'post__in'  => get_option( 'sticky_posts' ),
                'ignore_sticky_posts' => 1
            );
            $my_query = new WP_Query( $args );

            $do_not_duplicate = array();
            while ( $my_query->have_posts() ) : $my_query->the_post();
            $do_not_duplicate[] = $post->ID; ?>

<div id="post-<?php the_ID(); ?>" <?php post_class( '' ); ?> >
        <div class="featuredimage">
            <a href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>"><?php the_post_thumbnail('home-thumbnail'); ?></a>
        </div>
        <h2><a href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>
        </div>
<?php endwhile; ?>
<?php wp_reset_postdata(); //VERY VERY IMPORTANT?>
            </div>
<div id="gridcontainer">
<?php
$counter = 1; //start counter

$grids = 2; //Grids per row

global $query_string; //Need this to make pagination work

if ( have_posts() ) : while ( have_posts() ) : the_post();
if ( $post->ID == $do_not_duplicate ) continue; ?>
<?php
//Show the left hand side column
if($counter == 1) :
?>
        <div id="post-<?php the_ID(); ?>" <?php post_class( 'griditemleft' ); ?> >
            <div class="postimage">
                <a href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>"><?php the_post_thumbnail('home-thumbnail'); ?></a>
            </div>
                    <h2><a href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>
        </div>
<?php
//Show the right hand side column
elseif($counter == $grids) :
?>
<div id="post-<?php the_ID(); ?>" <?php post_class( 'griditemright' ); ?>>
            <div class="postimage">
                <a href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>"><?php the_post_thumbnail('home-thumbnail'); ?></a>
            </div>
            <h2><a href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>
</div>

<div class="clear"></div>
<?php
    $counter = 0;
    endif;
?>
<?php
    $counter++;
    endwhile;
    //Pagination can go here if you want it.
    endif;
?>
<?php
    untitled_content_nav( 'nav-below' );
?>
</div>

        </div><!-- #content -->
    </div><!-- #primary -->

IN FUNCTIONS.PHP

/*===================================================================================
* Homepage sticky filter in loop 2
* =================================================================================*/
add_action('pre_get_posts', 'wpse161279_ignore_sticky_posts');
// the function that does the work
function wpse161279_ignore_sticky_posts($query)
{
    if (!is_admin() && $query->is_main_query()) {
        $sticky = get_option( 'sticky_posts' );
        $query->set( 'post__not_in', array( $sticky[0] ) );
    }   
}
3
  • I'd really appreciate some help
    – xtojump
    Commented Sep 22, 2014 at 7:29
  • You are not very clear. Do you need to display the sticky in loop one or two Commented Sep 22, 2014 at 7:32
  • Hi Pieter, In loop 1 : Just the latest sticky OR the latest post. In loop 2 : All other latest posts and stickies (basically everything that's not in loop 1).
    – xtojump
    Commented Sep 22, 2014 at 7:33

2 Answers 2

2

You can adapt your first loop to either show a sticky post or the latest post in the following manner: PLEASE NOTE: You have to reset your custom query

<?php 

$args = array(
    'posts_per_page' => 1,
    'post__in'  => get_option( 'sticky_posts' ),
    'ignore_sticky_posts' => 1
);
$my_query = new WP_Query( $args );

$do_not_duplicate = array();
while ( $my_query->have_posts() ) : $my_query->the_post();
    $do_not_duplicate[] = $post->ID; ?>

<div id="post-<?php the_ID(); ?>" <?php post_class( '' ); ?> >
            <div class="featuredimage">
                <a href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>"><?php the_post_thumbnail('home-thumbnail'); ?></a>
            </div>
            <h2><a href="<?php the_permalink(); ?>" title="<?php the_title_attribute(); ?>"><?php the_title(); ?></a></h2>
        </div>
  <?php endwhile; ?>
  <?php wp_reset_postdata(); //VERY VERY IMPORTANT?>

Source: Sticky Posts

EDIT

The remove sticky posts from the main query, you can make use of the pre_get_posts action to remove sticky posts before the main query executes. Paste the following in your functions.php

add_action('pre_get_posts', 'wpse161279_ignore_sticky_posts');
// the function that does the work
function wpse161279_ignore_sticky_posts($query)
{
    if (!is_admin() && $query->is_main_query())
        $query->set('post__not_in', get_option('sticky_posts'));
}

EDIT 2

I haven't tested this, nor am I familiar with this, but I think you can try to do the following

add_action('pre_get_posts', 'wpse161279_ignore_sticky_posts');
// the function that does the work
function wpse161279_ignore_sticky_posts($query)
{
    if (!is_admin() && $query->is_main_query()) {
        $sticky = get_option( 'sticky_posts' );
        $query->set( 'post__not_in', array( $sticky[0] ) );
    }   
}

EDIT 3

Paste the following code just after line 4 in your first block of code in your question and then post the results

<pre><?php var_dump($wp_query->query_vars['post__not_in']); ?></pre>    
<pre><?php var_dump(get_option( 'sticky_posts' )); ?></pre>
<pre><?php var_dump($wp_query->query_vars['ignore_sticky_posts']); ?></pre>

You should get results familiar than these

enter image description here

EDIT 4

Add the following to the code above. This will print the ID of the first post. If it matches the second value of the second result, it means that your sticky post is actually displayed like it should

<pre><?php var_dump($wp_query->posts[0]->ID); ?></pre>

EDIT 5

FYI, this is how your site looks on my side. I have just removed the text parts and kept the images

enter image description here

22
  • It doesn't work. I've updated my question with all the code I currently have.
    – xtojump
    Commented Sep 22, 2014 at 16:29
  • What do you mean by doesn't work. You will need to explain Commented Sep 22, 2014 at 16:34
  • The sticky shown in loop 1 is also shown at the top of loop 2, and the other stickies which aren't shown in loop 1 don't show in loop 2.
    – xtojump
    Commented Sep 22, 2014 at 16:40
  • This is strange, it works perfectly on my site. You did not by change also use the code in edit 1. Commented Sep 22, 2014 at 16:52
  • I checked and I didn't use the code in edit 1 anywhere. If you want me to let you into the wp-admin I don't mind, email me: [email protected].
    – xtojump
    Commented Sep 22, 2014 at 16:55
2

There's a much simpler way and lighter way.
By definition sticky posts will come first on the loop.
So on your featured area (before any call to the_post() ) you can put:

<div>
   <h3>Special Featured Loop</h3>
   <?php the_post(); //this will get the first post, and generate all the tags the_title(), the_permalink(),... ?>  
   <h2 class="entry-title">
      <a href="<?php the_permalink(); ?>" rel="bookmark"><?php the_title(); ?></a>
   </h2>
</div>

Don't need to reset because you want to ignore the previous article.
To ignore sticky post you can use the is_sticky() function.
On your main loop you can put this:

<div>
    <h3>Loop ignoring the sticky posts</h3>
    <?php while ( have_posts() ) : the_post(); ?>
        <?php if(is_sticky()) continue; //ignore sticy posts?>
        <h2 class="entry-title">
            <a href="<?php the_permalink(); ?>" rel="bookmark"><?php the_title(); ?></a>
        </h2>
    <?php endwhile; // End the loop. Whew. ?>       
</div>

Hope that this helps you.

Cheers

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.