I spent days figuring out the code in "Adding next & previous links for node types within taxonomy terms (e.g. Image Galleries)" posting http://drupal.org/node/45050, a very useful enhancement for the Image module. In the process I learned a lot about the great Drupal features like database abstraction layer, pager, taxonomy, and functions for almost anything you can think of.

Here are my two versions of the “pager”.

=================================================

1. << first < previous [13 of 21] next > last >>

I prefer this version. It's simpler and offers more flexibility. It can be easily modified to generate a Drupal pager look-alike:

<< first < previous ... 2 3 4 5 6 7 8 9 10 ... next > last >>

I have added the following to node-image.tpl.php (a copy of node.tpl.php in your theme folder). The $page != 0 and $terms conditions ensure that the pager is printed only when the image is displayed as a standalone page and it belongs to a Gallery (has a term). The $class variable is optional, use it for CSS styling.

  <div class="pager">
    <?php if ($page != 0 && $terms) { print custom_pager($node->nid); } ?>
  </div>

I have created a custom.module for all my custom functions (PHP snippets), including the following custom_pager:

function custom_pager($current_nid, $class = NULL) {
  $tid = reset(array_keys(taxonomy_node_get_terms($current_nid)));
  $result = db_query(db_rewrite_sql('SELECT n.nid, n.title FROM {node} n INNER JOIN {term_node} tn ON n.nid = tn.nid WHERE tn.tid = %s AND n.status = 1 ORDER BY n.sticky DESC, n.created DESC, n.nid DESC'), $tid);
  while ($node = db_fetch_object($result)) {
    $nodes[++$i] = $node;
    if ($node->nid == $current_nid) $x = $i;
  }
  if($x > 1) {
    $output .= l('&laquo; first', 'node/'. $nodes[1]->nid, array('title' => check_plain($nodes[1]->title), 'class' => $class), NULL, NULL, FALSE, TRUE);
    $output .= l('&lsaquo; previous', 'node/'. $nodes[$x-1]->nid, array('title' => check_plain($nodes[$x-1]->title), 'class' => $class), NULL, NULL, FALSE, TRUE);
  }
  $output .= $x .' of '. $i;
  if($x < $i) {
    $output .= l('next &rsaquo;', 'node/'. $nodes[$x+1]->nid, array('title' => check_plain($nodes[$x+1]->title), 'class' => $class), NULL, NULL, FALSE, TRUE);
    $output .= l('last &raquo;', 'node/'. $nodes[$i]->nid, array('title' => check_plain($nodes[$i]->title), 'class' => $class), NULL, NULL, FALSE, TRUE);
  }
  return $output; 
}

========================================================

2. << first < previous [Back to Gallery] next > last >>

Add this to node-image.tpl.php (note that the node is passed to the function instead of the node ID):

  <div class="pager">
    <?php if ($page != 0 && $terms) { print custom_pager($node); } ?>
  </div>

And the function:

function custom_pager($node, $class = NULL) {
  if (!isset($node->taxonomy)) {
    $tid = reset(array_keys($node->taxonomy));
  }
  else {
    $tid = reset(array_keys(taxonomy_node_get_terms($node->nid)));
  }
  $prev = db_fetch_object(db_query_range(db_rewrite_sql('SELECT n.nid, n.title FROM {node} n INNER JOIN {term_node} tn ON n.nid = tn.nid WHERE tn.tid = %d AND (n.sticky > %d OR (n.sticky = %d AND (n.created > %d OR (n.created = %d AND n.nid > %d)))) AND n.nid != %d AND n.status = 1 ORDER BY n.sticky ASC, n.created ASC, n.nid ASC'), $tid, $node->sticky, $node->sticky, $node->created, $node->created, $node->nid, $node->nid, 0, 1));
  $next = db_fetch_object(db_query_range(db_rewrite_sql('SELECT n.nid, n.title FROM {node} n INNER JOIN {term_node} tn ON n.nid = tn.nid WHERE tn.tid = %d AND (n.sticky < %d OR (n.sticky = %d AND (n.created < %d OR (n.created = %d AND n.nid < %d)))) AND n.nid != %d AND n.status = 1 ORDER BY n.sticky DESC, n.created DESC, n.nid DESC'), $tid, $node->sticky, $node->sticky, $node->created, $node->created, $node->nid, $node->nid, 0, 1));
  if($prev) {
    $first = db_fetch_object(db_query_range(db_rewrite_sql('SELECT n.nid, n.title FROM {node} n INNER JOIN {term_node} tn ON n.nid = tn.nid WHERE tn.tid = %s AND n.status = 1 ORDER BY n.sticky DESC, n.created DESC, n.nid DESC'), $tid, 0, 1));
    $output .= l('&laquo; first', 'node/'. $first->nid, array('title' => check_plain($first->title), 'class' => $class), NULL, NULL, FALSE, TRUE);
    $output .= l('&lsaquo; previous', 'node/'. $prev->nid, array('title' => check_plain($prev->title), 'class' => $class), NULL, NULL, FALSE, TRUE);
  }
  if($prev || $next) {
    $gallery = taxonomy_get_term($tid);
    $count = taxonomy_term_count_nodes($tid);
    $output .=  l(check_plain($gallery->name) .' ('. $count .')', 'image/tid/'. $tid, array('title' => check_plain($gallery->name), 'class' => $class));
  }
  if($next) {
    $last = db_fetch_object(db_query_range(db_rewrite_sql('SELECT n.nid, n.title FROM {node} n INNER JOIN {term_node} tn ON n.nid = tn.nid WHERE tn.tid = %s AND n.status = 1 ORDER BY n.sticky ASC, n.created ASC, n.nid ASC'), $tid, 0, 1));
    $output .= l('next &rsaquo;', 'node/'. $next->nid, array('title' => check_plain($next->title), 'class' => $class), NULL, NULL, FALSE, TRUE);
    $output .= l('last &raquo;', 'node/'. $last->nid, array('title' => check_plain($last->title), 'class' => $class), NULL, NULL, FALSE, TRUE);
  }
  return $output; 
}

http://osherl.com