add a first, previous, next, last to any page, for any node type

Last modified: February 4, 2008 - 07:40

Note from a moderator. This page has been updated with code from the comments that is written more to the "Drupal way" than the original code and removes some misinformation (notably the original page stated that db_fetch_array($query) is for postgresql only and that is incorrect). The following changes are in the newer code:

1. loops once, not once for every link; I mean, call the function one time and make a single database call, so we can loop through the (possibly quite large) result set only one time ( not do all that for each link ).
2. use l(t()) calls for outputting the links
3. use drupal_sql_query code instead of mysql unique code
4. combined the three loops into one easy, single loop
5. modify the first 6 lines or the function arguments to use your node types
6. If you are using the Category module ( I can't speak for Taxonomy users) the next/previous/oldest links all reference the next/previous/oldest within that category, out of the box.
7. renamed the FIRST link to OLDEST and the LAST to LATEST.
8. This orders nodes by their created times, not by their edited times, and not by simply node number.

You need to edit your template.php file (located at: /themes/your_drupal_theme/template.php) and add the following code:

<?php
function get_nav_node_path($current_nid) {
   
// first need to check if we are looking at a category node and not a real node
   
$result = db_query("select type from node where nid = $current_nid");
   
$line = db_fetch_array($result);
    if (
$line[type] != 'page') return ''// do not show these links for category nodes, only for page nodes
    // Performing SQL query
   
$dbuid = get_session('dbuid');  // drupal browse user_id; I save this in my sessions to limit to users
   
$query = "select nid from node where type='page' AND user_id = $dbuid order by created desc";
   
$result = db_query($query) ;
   
//setup variables
   
$counter = 0;
   
$ary = array();
   
$node_location = 0;
   
$first =''; $previous=''; $next = ''; $last = ''; $next_nid = '';


   
//parse database and put into PHP array
   
while ($line = db_fetch_array($result)) {
          
$ary[$counter] = $line[nid];
           if(
$line[nid] == $current_nid) {
              
$node_location = $counter;
           }
          
$counter ++;
    }


   
$return = '<div id="nav-links">';
   
//tack on relative path of the first node
   
$print_nid = $ary[$counter - 1];
    if (
$print_nid != $current_nid ) {
       
$first = drupal_get_path_alias("node/$print_nid");
       
$return .=  l(t('Oldest'), $first);
    }


   
//tack on relative path of the previous node
   
if($node_location >= 0 && $node_location < $counter - 1) {
       
$print_nid = $ary[$node_location + 1];
       
$previous = drupal_get_path_alias("node/$print_nid");
        if (
$first != '') { $return .= ' | '; }
       
$return .=  l(t('Previous'), $previous);
    }



   
//tack on relative path of the next node
   
if($node_location > 0 && $node_location < $counter) {
       
$next_nid = $ary[$node_location - 1];
       
$next = drupal_get_path_alias("node/$next_nid");
        if (
$previous != '' || ($first !='' && $previous == '') ) { $return .= ' | '; }
       
$return .=  l(t('Next'), $next);
    }

    
//tack on relative path of the last node
   
if ($next_nid != $ary[0]) { // i.e. if next_nid is not the last one
       
$print_nid = $ary[0];
        if (
$print_nid != $current_nid ) {
           
$last drupal_get_path_alias("node/$print_nid");
            if (
$next != '' ) $return .= ' | '. l(t('Latest'), $last);
        }
    }

   
$return .= '</div>';
    return
$return;
}
?>

Now you just need to insert the following code into your node.tpl.php or whatever custom tpl file you like:

  <div class="node<?php if ($sticky) { print " sticky"; } ?><?php if (!$status) { print " node-unpublished"; } ?>">
    <?php if ($picture) {
      print
$picture;
    }
?>

    <?php if ($page == 0) { ?><h2 class="title"><a href="<?php print $node_url?>"><?php print $title?></a></h2><?php }; ?>
    <span class="submitted"><?php print $submitted?></span>
    <span class="taxonomy"><?php print $terms?></span>
<?
global $q;
if ($q != 'node') {   // my default page lists 5~10 entries and
// we don't need the next-prev-last-oldest links when we are simply browsing them.
// So check and only call the function when viewing an individual node
    echo get_nav_node_path($node->nid);
}
?>
    <div class="content"><?php print $content?></div>
    <?php if ($links) { ?><div class="links">&raquo; <?php print $links?></div><?php }; ?>
  </div>

 
 

Drupal is a registered trademark of Dries Buytaert.