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.
- In a text editor like notepad.exe or equivalent, create/edit a template.php file and paste the following snippet
- 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 .' '. $previous;}
print ' ['. $gallery .'] ';
if ($next){ print $next .' ' .$last;}
print '</center></p>';
}
?>notes
- once added to your template.php file, the
next_prevfunction maybe called from any custom layout.tpl.php file. - Please add a comment/child page with examples of using the custom
next_prevfunction in your layout.tpl.php files.

Small fix to step 1
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));
}
}
?>