Since Drupal 7 the CCK module is for a large part integrated into the Drupal core. You can very easily create and add new fields to a certain node type. One of the available field types is “field_image”. You can set the setting that multiple images are allowed.

If you create a view that displays all the node teasers, the images will be visible there. That all images are appended is nice, but actually only for the full node and not the teaser. So if you only want one image to show in the teaser you have to override the “template_preprocess_field” function. There is unfortunately no cleaner way.

Make sure you rename “mytemplatename” in your own template name. In the code below I only give this behaviour to the node type “project”. Look closely for the comment line “// Show only 1 image of possible multiple images in the teaser of a project”. Right below that line is where the action happens. A large part of this code is just a copy of the original function, but there is no smaller, cleaner, better override possible than this.

/**
 * Override or insert variables into fields
 *
 * @param type $variables
 * @param type $hook
 */

function mytemplatename_preprocess_field(&$variables, $hook) {
  $element = $variables['element'];
 
  // There's some overhead in calling check_plain() so only call it if the label
  // variable is being displayed. Otherwise, set it to NULL to avoid PHP
  // warnings if a theme implementation accesses the variable even when it's
  // supposed to be hidden. If a theme implementation needs to print a hidden
  // label, it needs to supply a preprocess function that sets it to the
  // sanitized element title or whatever else is wanted in its place.
  $variables['label_hidden'] = ($element['#label_display'] == 'hidden');
  $variables['label'] = $variables['label_hidden'] ? NULL : check_plain($element['#title']);

  // We want other preprocess functions and the theme implementation to have
  // fast access to the field item render arrays. The item render array keys
  // (deltas) should always be a subset of the keys in #items, and looping on
  // those keys is faster than calling element_children() or looping on all keys
  // within $element, since that requires traversal of all element properties.
  $variables['items'] = array();
   
  $i = 0;
  foreach ($element['#items'] as $delta => $item) {
    // Show only 1 image of possible multiple images in the teaser of a project
    if (isset($element['#view_mode']) && $element['#view_mode'] == 'teaser'
      && $element['#field_type'] == 'image' && $element['#bundle'] == 'project') {
      if ($i > 0) {
        break;
      }
    }
   
    if (!empty($element[$delta])) {
      $variables['items'][$delta] = $element[$delta];
      $i++;
    }
  }

  // Add default CSS classes. Since there can be many fields rendered on a page,
  // save some overhead by calling strtr() directly instead of
  // drupal_html_class().
  $variables['field_name_css'] = strtr($element['#field_name'], '_', '-');
  $variables['field_type_css'] = strtr($element['#field_type'], '_', '-');
  $variables['classes_array'] = array(
    'field',
    'field-name-' . $variables['field_name_css'],
    'field-type-' . $variables['field_type_css'],
    'field-label-' . $element['#label_display'],
  );
  // Add a "clearfix" class to the wrapper since we float the label and the
  // field items in field.css if the label is inline.
  if ($element['#label_display'] == 'inline') {
    $variables['classes_array'][] = 'clearfix';
  }

  // Add specific suggestions that can override the default implementation.
  $variables['theme_hook_suggestions'] = array(
    'field__' . $element['#field_type'],
    'field__' . $element['#field_name'],
    'field__' . $element['#bundle'],
    'field__' . $element['#field_name'] . '__' . $element['#bundle'],
  );
}