Conditional page/post navigation links in WordPress (redux)

After more helpful input, I’ve decided to update my original solution.

Instead of overriding four WordPress functions and adding two new ones in my functions.php file, I have slimmed it down to just one:

/**
 * If more than one page exists, return TRUE.
 */
function show_posts_nav() {
	global $wp_query;
	return ($wp_query->max_num_pages > 1);
}

This function will tell me if there is more than one page…and if there is, I will show the posts navigation (next_posts_link and previous_posts_link). I updated my WordPress (index.php, archive.php and search.php) files with:

<?php if (show_posts_nav()) : ?>
<div class='navigation'>
	<span class='older'><?php next_posts_link('&laquo; Older Entries'); ?></span>
	<span class='newer'><?php previous_posts_link('Newer Entries &raquo;'); ?></span>
</div>
<?php endif; ?>

As for the single post next/previous links, I decided to remove the check because I’ll always have more than one entry.

Much cleaner and less code 😉

42 thoughts on “Conditional page/post navigation links in WordPress (redux)”

  1. Hi Eric,
    I come from the JQuery-List to you to read about your fine Modal. And what i see here, this fine solution for a long problem with WP. I’m verry happy, thank you.

  2. @Olaf – Thanks, I’m glad it is useful for you. I was surprised that this functionality wasn’t built in to WordPress; maybe it will be in a future version.

  3. Thanks, I was trying to do this myself just now and noticed they use echo() on those functions so I couldn’t test them with empty().

    🙂

  4. Thanks for this idea for sharing!
    Now I have built it into my theme that I’m building for release and it is super!
    No empty divs from now!
    Thanks a lot!
    Andris

  5. I’m not sure how to use this. I tried putting the first code (as is) in my function.php and the second code (as is) in index.php, archives.php and search.php in my theme template files and my pages return with and error at the bottom where the Older Entries link used to be. What am I doing wrong?

  6. I just spent an hour looking for a solution to this problem before I found your site. Thanks a lot for posting this. Great work!

  7. Hey, I am currently migrating from serendipity and I am stumbling upon a couple of things which ar better solved there, because with smarty you get all those things as variables instead of an echo().
    But things like your solution here help a lot!

  8. btw: “because I’ll always have more than one entry” -> might be different for search results. that’s where I needed the code. 😉

  9. @mark – One thing I’ve seen is the ability to pass a boolean that indicates whether you want the value returned or echoed out. I think it would be helpful if WordPress included that type of option for some of its API function.

    To your second comment, I use this in my search.php file as well, just not in single.php. Is that what you were referring to?

  10. hi
    i am first time using wordpress
    but i would like to put a page and a post in the home page
    the post is actually a welcome post
    whereas the page is for news
    how can i do that?

  11. return ($wp_query->max_num_pages > 1) ? TRUE : FALSE;
    The ternary operator is unnecessary, as the comparison returns a boolean T/F value.

    You can just do this:
    return ($wp_query->max_num_pages > 1);

    and it will return the same thing. Using the ternary operator essentially says "If the statement 'max_num_pages > 1' returns true, then return true". 🙂

  12. Correct me if I’m wrong here, but doesn’t this just replace the problem of an empty div with an empty span tag (if there is not both a previous and next post)?

    I fail to see how that’s much of an improvement. I’m trying to figure out how to do this with list items rather than spans (the semantically correct way), and can’t seem to figure it out.

  13. @Pankaj – Not sure. All that needs to be done is to put a display parameter, like on some of their other functions, which would allow you to have the value returned as opposed to echo’d.

    @Dean – the point of this “work-around” was to only display the navigation div if it was needed. If you read my original post, you’ll see why I wanted to do that, but basically, it allows you to style the div and child elements and not worry about an empty “space” if no other pages/posts existed.

    As to your second point, why is using a list is more semantically correct for one item? Unless, of course, you are talking about building a list of pages, which is not what this post is about. This post is intended to show a function that would allow you to conditionally display the navigation elements, if so desired.

    If you’d like to share what problem you are having (or email me), I’d be happy to try and assist.

  14. Hi Eric,

    The semantically correct way to display a group of related links is an unordered list. In most cases, you will have two links – “newer posts” and “older posts”. But even when you only have one item, it’s still a list. Just as my list of “things to do today” is still a list, even when I’ve finished all tasks but the last one.

    Someone has already created a plugin to make the page numbers a list:

    https://wordpress.org/extend/plugins/epage-links/

    I would argue that that should probably be an ol, rather than a ul, but close enough 🙂

    The modification of your code I’m using is:

  15. @Dean – I think we’re splitting hairs here 😉 There are a number of pagination plugins but I’m implementing my own for a new theme I’m working on.

    As you might have notice, the code that you were trying to display did not show up. You need to make sure to escape you HTML entities.

  16. Hi Eric,

    I am looking for way to let me navigate from children page to the next children page and if there isn’t then it will go to the next category parent. I tried all 3 methods (new and older one beside the one on the forums) but they didn’t work for me. Can you help me with this?

  17. Hmmmm this seems useful, but following up on someone’s comment I DO need it for single.php.

    Basically my problem is that I only want to show my link separator if both Next & Previous Links exist (currently an — html equiv.). The posts_nav_link includes a separator as one of the parameters, any idea how to accomplish this for single.php? I want to keep the same links from index.php to single.php — where you would see “PREVIOUS POST >>” and not “— PREVIOUS POST >>”.

  18. does this code pull “newer posts” nav and “older posts” nav seperately? as in, if i have older posts but not newer, will it only display an older posts nav, etc?

  19. @Wisam – sounds like you need to do some custom coding in your functions.php file to handle that.

    @Marcy – were you able to get it working? Checked out your site – you do nice work!

    @CyruzDraxs – sorry, this is just for posts, not comments.

    @fyodor – Haha – glad you didn’t throw it out 😉 If you look at the second section of code, you’ll see where each part (prev, next) are being called.

  20. What CyruzDraxs said – is there any chance that you would be kind enough to do a version for the fancy new comments system?

  21. Hi,
    Good job!
    However, you have hardcoded the max_num_pages to compare with 1.
    At my site learn chinese online, I have used Custom Post Limits plugin from https://coffee2code.com/wp-plugins/custom-post-limits/ where it allows users to define the limits for front page, categories, archives,etc.

    Currently I fixed the limits to a certain value and compare max_num_pages with that value.

    Does anyone know how to get the dynamic limits for each of those different sections?

  22. Pingback: Anatomy of an HTML5 Wordpress theme — Nicolas Gallagher — Blog & Ephemera

  23. @Min Min- max_num_pages is calculated using those variables, so you should be fine comparing it it to 1.

    @Tracy – Sounds like a WordPress issue, not something caused by this code. It could be any number of things…

    @Jeff – good catch, thanks! I’ve updated the post with the correction.

Comments are closed.

Scroll to Top