Support » Developing with WordPress » Strange error with get_next_post() and get_previous_post()

  • Hi all,

    a strange error occurs in my customised posts navigation. I have a post type ‘projekt’, as you can see below.

    I want the posts navigation to navigate between all posts at this overview page, but when you click on one of the posts to see the single post view, you’ll notice that when clicking the next post link below the images, the last post of the overview list is missing. The other way round, it works well, the previous post link loops through all posts, not missing one.

    echo '
    <p class="post-navigation">';
    $kat = $_GET['kat'];
    if(!$kat) {
    	$category= get_the_category();
    	$kat = $category[0]->slug;
    $exclude_cats = array();
    $cats = get_categories();
    foreach($cats as $cat) {
    	if($cat->slug != $kat) $exclude_cats[] = $cat->term_id;
    if( get_next_post(false, $exclude_cats) ) {
    	$next_post = get_next_post(false, $exclude_cats);
    	echo '<a class="previous-post-link" href="' . add_query_arg('kat',$kat,get_permalink($next_post->ID)) . '">'.__('&laquo; previous project in this category','mathez').'</a>';
    } else { 
    	$first = new WP_Query('posts_per_page=1&post_type=projekt&order=ASC&category_name='.$kat); $first->the_post();
    	echo '<a class="previous-post-link last" href="' . add_query_arg('kat',$kat,get_permalink()) . '">'.__('&laquo; previous project in this category','mathez').'</a>';
    if( get_previous_post(false, $exclude_cats) ) { 
    	$previous_post = get_previous_post(false, $exclude_cats);
    	echo '<a class="next-post-link" href="' . add_query_arg('kat',$kat,get_permalink($previous_post->ID)) . '">'.__('next project in this category &raquo;','mathez').'</a>';
    } else { 
    	$last = new WP_Query('posts_per_page=1&post_type=projekt&order=DESC&category_name='.$kat); $last->the_post();
    	echo '<a class="next-post-link first" href="' . add_query_arg('kat',$kat,get_permalink()) . '">'.__('next project in this category &raquo;','mathez').'</a>';
    $page = get_page_by_path($kat);
    echo '<a href="'.get_permalink($page->ID).'">'.__('Back to project overview','mathez').'</a>';
    echo '</p>';

    (Unfortunately, I can’t use the default posts navigation here, as I need extra query args to be added to the posts navigation links and also I want to loop to the first/last post. If you have any idea of how to achieve the needed result using another solution, please let me know.)

    Thanks for your help!

    Kind regards

    • This topic was modified 4 years, 6 months ago by winnewoerp. Reason: better code display

    The page I need help with: [log in to see the link]

Viewing 4 replies - 1 through 4 (of 4 total)
  • Moderator bcworkz


    It appears your overview posts are not ordered by post date. The next/previous post link queries depend on post date ordering to determine the post to link to. When the query for overview posts does not match the post link query, things will not work correctly.

    Any time you depart from the normal way WP does things, when it comes to next/previous links and pagination, you are better off managing this yourself instead of relying on WP functions. This is often not as complicated as you may think. The WP functions have a lot of options built in which you probably have no need of, so referring to the WP source code for guidance can be more confusing than helpful.

    The important thing is the query for the next/previous post needs to be virtually the same as the overview query. The only difference would be the LIMIT clause. You can think of the next post query as a pagination query using offsets where the posts per page is one. If you keep track of what “page” is being displayed, you can sync up next/previous links with what’s displayed on overview.

    Thread Starter winnewoerp


    @bcworkz, this is a really helpful answer, thank you very much! I will work on my solution now and post it here when it’s ready.

    Thread Starter winnewoerp


    I’m sorry, I need one more clarfificaton before I can continue.

    If you keep track of what “page” is being displayed, you can sync up next/previous links with what’s displayed on overview.

    How would I achieve this? How can I know in the single post view what “page” is being displayed from the overview list? In the overview list I don’t have the “1 post per page” setting and I have no idea of how to keep track of the position in the list except when passing an extra query arg to the single view, which certainly is not the best way to do this.

    Moderator bcworkz


    No need for apology, all questions welcome! That’s a good question. It depends on how the overview posts are ordered. The default pagination uses the post date/time as a “current page” mechanism. The next post query to determine what link to output simply queries for a single post with a date/time later than the current post’s date/time. You can use the same technique for whatever ordering criteria is used.

    For example, if the overview is ordered alphabetically, the next post can be queried by getting a single post whose title is alphabetically later than the current post’s title. Where things get tricky is with arbitrary ordering. For example, the default WP gallery orders posts by a list of IDs passed to the [gallery] shortcode. That list is the only way to know what the next/previous post is. The shortcode handler would need to somehow use this to make the next/previous post be known to pagination template tags.

    The gallery shortcode doesn’t do this AFAIK, so when one manually rearranges the gallery order, the next/previous links on single post templates do not work correctly.

    The only other way to keep track of the current “page” between requests is by passing a value somehow, such as an URL parameter. As you say, this is less than optimal. Any of the other usual options for maintaining persistent values could also be used, such as cookies, session vars, transients, user meta, etc.

    Alternately, the single post loop could assign next/previous post IDs to global vars which the pagination functions then can use to generate links. This assumes the main query driving the loop somehow is able to easily determine what the next/previous posts are.

Viewing 4 replies - 1 through 4 (of 4 total)
  • The topic ‘Strange error with get_next_post() and get_previous_post()’ is closed to new replies.