HowTo: Have "first" and "last" classes on list view LI's

Much like HowTo: Have "first" and "last" classes on menu blocks sometimes you need to be able to address the first and last elements of lists, this howto allows you to have that for your LI's.

The processing of lists is done by function theme_item_list($items = array(), $title = NULL, $type = 'ul', $attributes = NULL) which can be over ridden in template.php, it only takes a few small changes to get this to work (adding $item_key to the foreach and checking it against count and 0 to determine if to apply the class).

Paste the code below into your template.php and your done.

<?php

function phptemplate_item_list($items = array(), $title = NULL, $type = 'ul', $attributes = NULL) {
 
$output = '<div class="item-list">';
  if (isset(
$title)) {
   
$output .= '<h3>'. $title .'</h3>';
  }

  if (!empty(
$items)) {
   
$output .= "<$type" . drupal_attributes($attributes) . '>';
    foreach (
$items as $item_key=>$item) {
     
$attributes = array();
     
$children = array();
      if (
is_array($item)) {
        foreach (
$item as $key => $value) {
          if (
$key == 'data') {
           
$data = $value;
          }
          elseif (
$key == 'children') {
           
$children = $value;
          }
          else {
           
$attributes[$key] = $value;
          }
        }
      }
      else {
       
$data = $item;
      }
      if (
count($children) > 0) {
       
$data .= theme_item_list($children, NULL, $type, $attributes); // Render nested list
     
}
     
      if(
$item_key == 0) {
       
$attributes['class'] = (isset($attributes['class'])? $attributes['class'] .= ' first' : 'first');
      } elseif(
$item_key == count($items)-1){
       
$attributes['class'] = (isset($attributes['class'])? $attributes['class'] .= ' last' : 'last');
      }
     
     
$output .= '<li' . drupal_attributes($attributes) . '>'. $data .'</li>';
    }
   
$output .= "</$type>";
  }
 
$output .= '</div>';
  return
$output;
}
?>

Bonus: Zebra

Add the following before $output .= '<li' . drupal_attributes($attributes) . '>'. $data .'</li>'; to add a zebra class to alternate list items (not the php tags).

<?php
if ($item_key % 2) { $attributes['class'] = (isset($attributes['class'])? $attributes['class'] .= ' zebra' : $attributes['class'] = 'zebra'); }
?>

 
 

Drupal is a registered trademark of Dries Buytaert.