Adding next & previous links for node types within taxonomy terms (e.g. Image Galleries)

description

The following adds a custom next_prev function to your theme template.php file that allows you to insert NEXT | PREVIOUS type links in your layout.tpl.php files. Where layout might be node.tpl.php, node-image.tpl.php etc.

In the illustrative example snippet below, a simple NEXT | PREVIOUS link is inserted into a custom node-image.tpl.php file linking to the next and previous image within that gallery (taxonomy term).

step 1 of 2

Add the custom next_prev function to your template.php file.

  1. In a text editor like notepad.exe or equivalent, create/edit a template.php file and paste the following snippet
  2. Save your new/edited template.php file and upload it to your active theme folder

<?php
function next_prev($current_nid, $type, $button_type, $label, $class) {
  
$tid = db_result(db_query(db_rewrite_sql("SELECT tid FROM {term_node} WHERE nid = $current_nid;")));
   if (empty(
$tid)){ //validate that the image 'does' have a tid
   
return '';
   }

   switch (
$button_type) {
     case
'next':
      
$sort= 'DESC';
      
$case = '< ';
       break;
     case
'prev':
      
$sort = 'ASC';
      
$case = '> ';
       break;
     case
'parent':
      
$name = db_result(db_query(db_rewrite_sql("SELECT name FROM {term_data} WHERE tid = $tid;")));
       return
l($label.$name, "$type/tid/$tid", array('title' => $name, 'class' => $class));
       break;
     case
'last':
      
$sql  = "SELECT n.nid, n.title FROM node n INNER JOIN term_node t ON n.nid = t.nid";
      
$sql .= " INNER JOIN term_data r ON t.tid = r.tid WHERE n.type = '". $type ."'";
      
$sql .= " AND r.tid = $tid AND n.status = 1 ORDER BY nid ASC LIMIT 0 , 1";
      
$result = db_fetch_array(db_query(db_rewrite_sql($sql)));
       return
l($label, 'node/'. $result['nid'], array('title' => $result['title'], 'class' => $class));
       break;
     case
'first':
      
$sql  = "SELECT n.nid, n.title FROM node n INNER JOIN term_node t ON n.nid = t.nid";
      
$sql .= " INNER JOIN term_data r ON t.tid = r.tid WHERE n.type = '" .$type. "'";
      
$sql .= " AND r.tid = $tid AND n.status = 1 ORDER BY nid DESC LIMIT 0 , 1";
      
$result = db_fetch_array(db_query(db_rewrite_sql($sql)));
       return
l($label, 'node/'. $result['nid'], array('title' => $result['title'], 'class' => $class));
       break;
     default:
       return
NULL;
       break;
   }
  
$sql = "SELECT n.nid, n.title FROM {node} n INNER JOIN {term_node} t ON n.nid = t.nid ";
  
$sql .= "INNER JOIN {term_data} r ON t.tid = r.tid WHERE n.type = '". $type ."' AND n.nid ". $case;
  
$sql .= $current_nid ." AND r.tid = ". $tid ." AND n.status = 1 ORDER BY nid ". $sort;
  
$result = db_fetch_array(db_query(db_rewrite_sql($sql)));
   if (!
$result) {
     return
NULL;
     return
l($label.$name, "$type/tid/$tid", array('title' => $name, 'class' => $class));
   } else {
     return
l($label, 'node/'. $result['nid'], array('title' => $result['title'], 'class' => $class));
   }
}
?>

step 2 of 2

Insert this snippet in your custom layout.tpl.php file and edit the $node->type to suit. This example snippet is intended for a custom node-image.tpl.php file. It inserts a link to the NEXT and PREVIOUS image within that image gallery (taxonomy term).

<?php
 
if ($terms && arg(0) == 'node' && is_null(arg(2))) {
     
$next = next_prev($node->nid, 'image', 'next', 'next>', 'link'); // replace 'test' with a valid class for the link
     
$previous = next_prev($node->nid, 'image', 'prev', '<previous', 'link');
     
$last = next_prev($node->nid, 'image', 'last', 'last>>', 'link');
     
$first = next_prev($node->nid, 'image', 'first', '<<first', 'link');
     
$gallery = next_prev($node->nid, 'image', 'parent', '', 'link');
      print
'<p><center>';
      if (
$previous){ print $first .'&nbsp;&nbsp;'. $previous;}
      print
'&nbsp;&nbsp;['. $gallery .']&nbsp;&nbsp;';
      if (
$next){ print $next .'&nbsp;&nbsp;' .$last;}
      print
'</center></p>';
    }
?>

notes

  • once added to your template.php file, the next_prev function maybe called from any custom layout.tpl.php file.
  • Please add a comment/child page with examples of using the custom next_prev function in your layout.tpl.php files.

Small fix to step 1

bdimaggio - November 28, 2007 - 19:53

This is a super-useful piece of code and was working fine for me until I installed I18n, at which point I started getting a bunch of SQL errors like the following:
user warning: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ';)' at line 1 query: SELECT tid FROM term_node LEFT JOIN i18n_node i18n ON n.nid = i18n.nid WHERE (i18n.language ='en' OR i18n.language ='' OR i18n.language IS NULL) AND ( nid = 125;) in /home/digitao0/public_html/ecologic/includes/database.mysql.inc on line 172.

I fooled around with this a bit and discovered that some small changes to the SQL (adding brackets to all the tables that get referred to, removing the semicolon from the first SQL statement, adding a LEFT JOIN to bring the node table into that statement) fixed the problem. Here's what works for me:

<?php
 
function next_prev($current_nid, $type, $button_type, $label, $class) {
  
$tid = db_result(db_query(db_rewrite_sql("SELECT tn.tid FROM {term_node} tn LEFT JOIN {node} n ON tn.nid=n.nid WHERE tn.nid = $current_nid")));
   if (empty(
$tid)){ //validate that the image 'does' have a tid
   
return '';
   }
  
   switch (
$button_type) {
     case
'next':
      
$sort= 'DESC';
      
$case = '< ';
       break;
     case
'prev':
      
$sort = 'ASC';
      
$case = '> ';
       break;
     case
'parent':
      
// $name = db_result(db_query(db_rewrite_sql("SELECT name FROM {term_data} WHERE tid = $tid;")));
      
return l($label, "$type/tid/$tid", array('title' => $label, 'class' => $class));
       break;
     case
'last':
      
$sql  = "SELECT n.nid, n.title FROM {node} n INNER JOIN {term_node} t ON n.nid = t.nid";
      
$sql .= " INNER JOIN {term_data} r ON t.tid = r.tid WHERE n.type = '". $type ."'";
      
$sql .= " AND r.tid = $tid AND n.status = 1 ORDER BY nid ASC LIMIT 0 , 1";
      
$result = db_fetch_array(db_query(db_rewrite_sql($sql)));
       return
l($label, 'node/'. $result['nid'], array('title' => $result['title'], 'class' => $class));
       break;
     case
'first':
      
$sql  = "SELECT n.nid, n.title FROM {node} n INNER JOIN {term_node} t ON n.nid = t.nid";
      
$sql .= " INNER JOIN {term_data} r ON t.tid = r.tid WHERE n.type = '" .$type. "'";
      
$sql .= " AND r.tid = $tid AND n.status = 1 ORDER BY nid DESC LIMIT 0 , 1";
      
$result = db_fetch_array(db_query(db_rewrite_sql($sql)));
       return
l($label, 'node/'. $result['nid'], array('title' => $result['title'], 'class' => $class));
       break;
     default:
       return
NULL;
       break;
   }
  
$sql = "SELECT n.nid, n.title FROM {node} n INNER JOIN {term_node} t ON n.nid = t.nid ";
  
$sql .= "INNER JOIN {term_data} r ON t.tid = r.tid WHERE n.type = '". $type ."' AND n.nid ". $case;
  
$sql .= $current_nid ." AND r.tid = ". $tid ." AND n.status = 1 ORDER BY nid ". $sort;
  
$result = db_fetch_array(db_query(db_rewrite_sql($sql)));
   if (!
$result) {
     return
NULL;
     return
l($label.$name, "$type/tid/$tid", array('title' => $name, 'class' => $class));
   } else {
     return
l($label, 'node/'. $result['nid'], array('title' => $result['title'], 'class' => $class));
   }
}
?>

 
 

Drupal is a registered trademark of Dries Buytaert.