WordPress.org

Forums

WP_Query and paging problem (10 posts)

  1. vmandesign
    Member
    Posted 1 year ago #

    So I've got this code placed on both my index.php page and my single.php page.

    The idea is to show the most recent four posts, excluding the current post being displayed. I'd also like the next_posts_link and previous_posts_link to display the appropriate pages of results.

    The issue is that the code works perfectly on my index.php page, but on the single.php page, when you click on the next/prev page links it re-shows the same four posts.

    Please, can someone help me find out why the code is being treated differently?

    <?php
    global $paged;
    $this_post = $post->ID;
    $wp_query = new WP_Query();
    $wp_query->query(array('post__not_in' => array($this_post), 'posts_per_page' => 4, 'paged' => $paged)); ?>
    
    <?php while ($wp_query->have_posts()) : $wp_query->the_post(); ?>
    <div style="width: 224px; float: left; margin-right: 10px;">
    <a href="<?php the_permalink() ?>"><h4><?php the_title(); ?></h4></a><br />
    <a href="<?php the_permalink() ?>"><?php the_post_thumbnail(array(224,224)); ?></a>
    </div>
    <?php endwhile; ?>
    <div style="clear: both;"></div>
    <?php next_posts_link('&laquo; Older Entries', $wp_query->max_num_pages) ?>
    <?php previous_posts_link('Newer Entries &raquo;') ?>
    <?php wp_reset_query(); ?>
  2. Nate Reist
    Member
    Posted 1 year ago #

    what happens if you declare the global post variable before your wp_query?
    <?php global $post; ?>

    I also can't help but wonder what the $paged variable does on a single, considering it is not an archive when viewing a single, I think that would return nothing, try this before your query:

    <?php echo 'Paged: '.$paged.'<br/>'; ?>

    And see what it returns on the single.

  3. vmandesign
    Member
    Posted 1 year ago #

    Thank you for responding, natereist.

    I added the global post variable as suggested. Removed the global paged variable.

    I also added your <?php echo 'Paged: '.$paged.'
    '; ?> before the query. It returns a 0.

    It is acting the same.

  4. Nate Reist
    Member
    Posted 1 year ago #

    so because $paged = 0 it is always grabbing the first 4 posts. As long as paged isn't defined it won't grab anything but those 4 posts. You can define paged on your own, but it doesn't have a global value when you are on a single, because the post could be on different pages for different archives, categories, tags, etc.

    If you are trying to show the next 4 posts, you might try this on your single pages. get_adjacent_post

    <?php
    // get the 4 on the single posts.
    global $post;
    $i = 0;
    while( $i < 4 ){
    	$next_post = get_adjacent_post( false, '', false);
    
    	if( !empty( $next_post ) ){
    		$post = $next_post; // needs to be $post for setup_postdata...
    		setup_postdata( $post );
    		?>
    		<div style="width: 224px; float: left; margin-right: 10px;">
    		<a href="<?php the_permalink() ?>"><h4><?php the_title(); ?></h4></a><br />
    		<a href="<?php the_permalink() ?>"><?php the_post_thumbnail(array(224,224)); ?></a>
    		</div>
    		<?php
    	}
    	else{
    		echo 'not found';
    	} // end if
    	$i++;
    } // end while
    wp_reset_postdata(); // reset your post
    ?>
    <div style="clear: both;"></div>
    <?php next_post_link(); ?>
    <?php previous_post_link(); ?>
  5. vmandesign
    Member
    Posted 1 year ago #

    Hey there,

    So I used the code you suggested.

    Now I get "not foundnot foundnot foundnot found" where the four posts should be on the most recent post.

    If I go to the second most recent post. I can see the most recent post as laid out in our code, but the other three are "not found".

  6. vmandesign
    Member
    Posted 1 year ago #

    Actually, it seems that I can get one adjacent post each time. The next_post and previous_post links are working, they are showing the title of the posts, and I can see the post on either side of the current post.

    EDIT:
    One issue I can see will come up is the fact that I'm trying to be able to pull four additional posts each time I click on the next_posts_link. I realize that this isn't going to happen with the next_post and previous_post links because they are only asking for one at a time.

  7. Nate Reist
    Member
    Posted 1 year ago #

    I guess the get_adjacent_post link will only get the adjacent one to the loaded post by the initial WP_Query.

    It looks as though you will need a more customized solution to pull the four after the current post.

    You could do something like getting the date of the current post, then run a new query to get posts after that date, see this post on stackoverflow. Here is a link to the WP_Query time parameters

    If you are just trying to get the most recent posts, you might check out this function: wp_get_recent_posts

  8. bcworkz
    Member
    Posted 1 year ago #

    If I may jump in here, the reason vmandesign's initial code does not work on single.php is because the content shown is based on a local query, but the posts_link navigation functions are working off the main global query.

    There's a number of possible approaches. natereist's suggestion of managing your own pagination with your own query will work. You might be able to fool the posts_link functions into working with your local query by copying your query into the global query (after backing up the initial global version) Once the posts_link functions are called, the original global query can be restored. I'm not totally sure this will work and I personally don't like trying to fool functions this way.

    The approach I would suggest is to hook the 'pre_get_posts' action. If the query is for a single post, alter the query variables to retrieve the four posts you want on that page, as well as setting the pagination variables to work as a 4 post per page index page.

    Then the single template can simply have it's original form with a WP loop without the need for a new query object. The posts_link navigation will then work properly without the need to swap queries. Furthermore, this is more efficient as only one query is run, instead of discarding the first single query and creating a new one.

  9. vmandesign
    Member
    Posted 1 year ago #

    Is there a way you can show how to update the code on the single.php page to make this happen?

  10. bcworkz
    Member
    Posted 1 year ago #

    I mentioned a few approaches, I'll assume you are referring to my preferred approach with the 'pre_get_posts' action.

    You would actually revert single.php back to whatever your theme normally does, presumably some variation of the standard WP Loop. All the good stuff happens in your callback to 'pre_get_posts', which would reside in functions.php (preferably that of a child theme rather than hacking your theme directly). See Plugin API/Action Reference/pre get posts for more information.

    Your callback would first use if(is_single()) {//the good stuff here} so your changes only apply to single post requests. You then set various query variables to alter the query to meet your needs. (The good stuff) The variable names are the same as the arguments used in new WP_Query($args) except instead of building an argument array, you use $query->set() to assign a value to each variable individually.

    I can't give you more specific code on how this is done, I don't code for anyone here except when it's something super simple and short. I prefer to help people learn rather than just hand out solutions.

Topic Closed

This topic has been closed to new replies.

About this Topic