Drupal 6: Creating a custom theme layout for a CCK node form

Sometimes the default theming layout of a CCK node cannot simply be adjusted using CSS. In this example, I’ll explain how to modify the layout of a CCK node form and group some form elements into a table, item list, etc. NOTE: this code has to reside in you template.php file.

<?php
// first, modify the theme registry so Drupal knows you'd like to override the theming of your CCK node type
function MYTHEME_theme($existing, $type, $theme, $path) {
  return array(
    'MYCCKTYPE_node_form' => array(
      'arguments' => array(
        'form' => NULL
      )
    )
  );
}

// now, define the function that will modify the structure of the form object
function MYTHEME_MYCCKTYPE_node_form($form) {

  // create a variable to store the form html
  $html = "";

  // loop through the $form object
  $fields = array();
  foreach ($form as $k => $v) {
    // check if the current key is a field
    if (substr($k, 0, 6)=='field_') {
      // NOTE: you can use the drupal_render() function to generate the output on $v
      // in this example, I'll create the html for each field and store it in an array
      $fields[$k] = drupal_render($v);

      // NOTE: since we're executing drupal_render on $v, and not directly on $form,
      // we'll have to remove this field from $form so it will not be rendered twice
      // Normally, drupal will not render a form object if it has already been rendered
      unset($form[$k]);

    }
  }

  // Now the html has been stored in the associative array $fields variable in the format:
  // [field name] => [field html]
  // At this point you could use a theme function
  // (theme_table, theme_item_list, theme_fieldset, etc)
  // to generate the html for a common layout format,
  // or you could create your own html/css layout
  // For example, you could put the fields in an item list:
  $html .= theme('item_list', array_values($fields));

  // Lastly, you'll need to generate the html for the rest of the form fields
  $html .= drupal_render($form);

  return $html;
}
?>

Here’s a screen shot of a CCK node form that I rebuilt in a table:

modified form layout

Updated: