wordpress post navigation hacks
This article covers using the global parameter $paged and the query $wp_query->max_num_pages; to create custom navigation links for previous and next posts. For some reason wordpress treats posts in the past as "next" and posts in the future as "previous" as explained in this exerpt from the WordPress website:
Note that since weblog posts are traditionally listed in reverse chronological order (with most recent posts at the top), there is some ambiguity in the definition of "next page". WordPress defines "next page" as the "next page toward the past". In WordPress 1.5, the default Kubrick (http://binarybonsai.com/kubrick) theme addresses this ambiguity by labeling the "next page" link as "previous entries".
The full article can be found here. Here's the html / php exerpt from the Kubrick theme:
<div class="navigation"> <div class="alignleft"> <?php posts_nav_link('','','« Previous Entries') ?> </div> <div class="alignright"> <?php posts_nav_link('','Next Entries »','') ?> </div> </div>
It's a simple solution but it doesn't work if you want to add a divider between the two links, for example: previous | next
Here's my first script which addresses that problem:
//output the previous link posts_nav_link('','', __('« Previous')); //set the divider $divider = ' | '; //get the current page number $page_num = $paged; //get the number of the final page $max_num_pages = $wp_query->max_num_pages; if($page_num == ''){$page_num = '1';} //if its not the first or last page display the divider if($page_num>1 && $page_num<$max_num_pages){echo $divider;} //display the next link posts_nav_link('', __('Next »'),'');
This next example works on a similar basis, but it displays the inactive link greyed-out. So on the first page the 'next' link would be displayed but inactive and with the css class 'greyed_out' attached to it. The same would apply to the 'previous' link on the final page. Here's the code:
//set the divider that separates the links $divider = ' | '; //get the current page number $page_num = $paged; if($page_num == ''){$page_num = '1';} //get the number of the last page $max_num_pages = $wp_query->max_num_pages; //if its the first page if($page_num>1){ posts_nav_link('','', __('previous posts')); echo $divider; echo'<span class="greyed_out">next posts</span>'; } //if its in the middle if($page_num>1 && $page_num<$max_num_pages){ posts_nav_link('','', __('previous posts')); echo $divider; posts_nav_link('', __('next posts'),''); } //if its the last page if($page_num == $max_num_pages){ echo'<span class="greyed_out">previous posts</span>'; echo $divider; posts_nav_link('', __('next posts'),''); }






Thanks for this interesting technique. I finally realized, though, that this works only for “paged” templates, like the index and categories and tag pages. Can you suggest a technique to use on single-post templates?
I understand that some of this functionality is built in to the next_post_link and previous_post_link tags already, but it is still difficult to make one of them go away if you are using them with nested divs or other complicated bits of CSS — because you don’t have direct access to the anchor tag. Any suggestions for crafting an equivalent “if” statement that will make the previous or next link not show when not needed on a single-post page?
Also, how much of a performance hit will the $wp_query call cause in the above code?
Hi Gus
With the next_post_link / previous_post_link functions you should use the ‘format’ parameter to keep your divs from displaying when the link is not needed. For example:
<div id="post_nav">
< ?php next_post_link('%link', 'Next Post'); ?>
</div>
will still display the div. While:
< ?php
$post_link_format='<div id="post_nav">%link</div>’;
next_post_link($post_link_format, ‘Next Post’); ?>
would only show the div when the link is needed.