For my portfolio site I wanted each image node (CCK + imagefield) to have a thumbnail strip of 10 or so images from the same category. Very simple stuff I thought. A quick search and I came across fantastic module called Custom Pagers by Eaton. This highly flexible module provides you a Next and Previous custom pager that you can display in your node pages. This was perfect for blog nodes but I wanted more control over the pager and I only wanted nodes to be pulled out from the same taxonomy term as the node being displayed.. fairly simple idea:
- hook_nodeapi - so we can intercept the current node
- Identify the term we want to target (you will need to adapt this for your own taxonomy)
- Pass the NID and TID to our custom pager function
- Select nodes from the db and process them
- return results to hook_nodeapi and add to node object
- print your custom pager in the node template
Example
Here is what the code looks like:
Step 1
Setup the hook_nodeapi
function mymodule_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL){ switch($op){ case 'view': //only apply to "mynode" node type if($node->type == "mynode" and $a3 == null and $a4 != null){ //loop through taxonomy if you need to foreach ($node->taxonomy as $term_obj){ //if its the right term vocab.. // do your custom code here if($term_obj->vid == 1){ //thumbnail custom pager $node->node_thumbnail_nav = mymodule_node_thumbnail_nav($node->nid, $term_obj->tid); } } } break; } }
Step 2
Function to return the custom pager nodes
function mymodule_node_thumbnail_nav($nid, $tid){ // current one will be added to the total later, // make sure number is always 1 less than the TOTAL displayed $total_thumbnails_to_display = 10; $left = ceil(($total_thumbnails_to_display) / 2); $right = floor(($total_thumbnails_to_display) / 2); $next_nids_array = mymodule_node_thumbnail_nav_db($nid, $tid, 'more', $total_thumbnails_to_display); $previous_nids_array = mymodule_node_thumbnail_nav_db($nid, $tid, 'less', $total_thumbnails_to_display); // if we dont have enough next (newer) items, pad with previous if(count($next_nids_array) < $right){ $previous_nids_array = array_splice($previous_nids_array, 0, $total_thumbnails_to_display - count($next_nids_array)); } // if we dont have enough previous (older) items, pad with next elseif(count($previous_nids_array) < $left){ $next_nids_array = array_splice($next_nids_array, 0, $total_thumbnails_to_display - count($previous_nids_array)); } // all good, splice in the center to get both left (older) and right (newer) nodes else{ $previous_nids_array = array_splice($previous_nids_array, 0, $left); $next_nids_array = array_splice($next_nids_array, 0, $right); } //merge left and right and add current node $all_nids_array = array_merge($next_nids_array, array($nid), $previous_nids_array); // sort the list sort($all_nids_array); //check if there is something to work with if(count($all_nids_array) != 0){ //we have our list, lets work though it foreach($all_nids_array as $available_nid){ $node_obj = node_load($available_nid); $current_nid_class = ""; //for the current nid we need a custom class to identify it if($available_nid == $nid){ $current_nid_class=' current_nid'; } $image = $node_obj->field_image_attach[0]['filepath']; $linked_image = l(theme('imagecache', 'photo_mini', $image, $node_obj->title, $node_obj->title), 'node/' . $node_obj->nid, array('html'=>true)); $thumbs .= "<div class=\"thumbnail_item{$current_nid_class}\">{$linked_image}</div>"; } return "<div class=\"thumbnail_container\">{$thumbs}</div>"; } }
Step 3
MySql DB query stuff
function mymodule_node_thumbnail_nav_db($nid, $tid, $op='more', $limit=10){ if($op == 'more'){ $op = '>'; $order = "ASC";} else{ $op = '<'; $order = "DESC";} $sql = " SELECT node.nid FROM node Inner Join term_node ON node.nid = term_node.nid WHERE node.type = 'mynode' AND node.status = 1 AND node.moderate = 0 AND node.nid %s %d AND term_node.tid = %d ORDER BY node.nid %s LIMIT %d "; $nids_array = array(); $result = db_query($sql, $op, $nid, $tid, $order, $limit); while($row = db_fetch_object($result)){ $nids_array[] = $row->nid; } return $nids_array; }
Step 4
Edit your node template and add
if($node->node_thumbnail_nav){ $print $node->node_thumbnail_nav;}
Step 5
Customise the output with your own CSS
Your thoughts and comments are most welcome.