Index: modules/node/content_types.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/node/content_types.inc,v retrieving revision 1.96 diff -u -r1.96 content_types.inc --- modules/node/content_types.inc 9 Oct 2009 01:00:00 -0000 1.96 +++ modules/node/content_types.inc 12 Oct 2009 06:32:38 -0000 @@ -132,25 +132,6 @@ '#collapsible' => TRUE, '#group' => 'additional_settings', ); - $form['submission']['title_label'] = array( - '#title' => t('Title field label'), - '#type' => 'textfield', - '#default_value' => $type->title_label, - '#required' => TRUE, - ); - if (!$type->has_title) { - // Avoid overwriting a content type that intentionally does not have a - // title field. - $form['submission']['title_label']['#attributes'] = array('disabled' => 'disabled'); - $form['submission']['title_label']['#description'] = t('This content type does not have a title field.'); - $form['submission']['title_label']['#required'] = FALSE; - } - $form['submission']['body_label'] = array( - '#title' => t('Body field label'), - '#type' => 'textfield', - '#default_value' => isset($type->body_label) ? $type->body_label : '', - '#description' => t('To remove the body field, remove text and leave blank.'), - ); $form['submission']['node_preview'] = array( '#type' => 'radios', '#title' => t('Preview before submitting'), @@ -305,13 +286,6 @@ $type->description = $form_state['values']['description']; $type->help = $form_state['values']['help']; - $type->title_label = $form_state['values']['title_label']; - $type->body_label = $form_state['values']['body_label']; - - // title_label is required in core; has_title will always be true, unless a - // module alters the title field. - $type->has_title = ($type->title_label != ''); - $type->has_body = ($type->body_label != ''); $type->base = !empty($form_state['values']['base']) ? $form_state['values']['base'] : 'node_content'; $type->custom = $form_state['values']['custom']; @@ -325,6 +299,11 @@ $status = node_type_save($type); + // Automatically add title and body fields to content types created through the UI. + if ($status == SAVED_NEW) { + node_type_default_fields($type); + } + $variables = $form_state['values']; // Remove everything that's been saved already - whatever's left is assumed Index: modules/node/node.api.php =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.api.php,v retrieving revision 1.39 diff -u -r1.39 node.api.php --- modules/node/node.api.php 10 Oct 2009 21:39:03 -0000 1.39 +++ modules/node/node.api.php 12 Oct 2009 06:32:39 -0000 @@ -596,14 +596,6 @@ * - "description": a brief description of the node type. Required. * - "help": help information shown to the user when creating a node of * this type.. Optional (defaults to ''). - * - "has_title": boolean indicating whether or not this node type has a title - * field. Optional (defaults to TRUE). - * - "title_label": the label for the title field of this content type. - * Optional (defaults to 'Title'). - * - "has_body": boolean indicating whether or not this node type has a body - * field. Optional (defaults to TRUE). - * - "body_label": the label for the body field of this content type. Optional - * (defaults to 'Body'). * - "locked": boolean indicating whether the administrator can change the * machine name of this type. FALSE = changable (not locked), * TRUE = unchangable (locked). Optional (defaults to TRUE). @@ -792,26 +784,15 @@ * edit form. * * The submit and preview buttons, taxonomy controls, and administrative - * accoutrements are displayed automatically by node.module. This hook - * needs to return the node title, the body text area, and fields - * specific to the node type. + * accoutrements are displayed automatically by node.module. Node title and + * body fields are handled by the Field API, so this hook does not need to + * describe them. It only needs to return elements specific to the node type. * * For a detailed usage example, see node_example.module. */ function hook_form($node, $form_state) { $type = node_type_get_type($node); - $form['title'] = array( - '#type' => 'textfield', - '#title' => check_plain($type->title_label), - '#required' => TRUE, - ); - $form['body'] = array( - '#type' => 'textarea', - '#title' => check_plain($type->body_label), - '#rows' => 20, - '#required' => TRUE, - ); $form['field1'] = array( '#type' => 'textfield', '#title' => t('Custom field'), Index: modules/node/node.install =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.install,v retrieving revision 1.33 diff -u -r1.33 node.install --- modules/node/node.install 11 Oct 2009 03:07:18 -0000 1.33 +++ modules/node/node.install 12 Oct 2009 06:32:39 -0000 @@ -288,34 +288,6 @@ 'not null' => TRUE, 'size' => 'medium', ), - 'has_title' => array( - 'description' => 'Boolean indicating whether this type uses the {node}.title field.', - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'size' => 'tiny', - ), - 'title_label' => array( - 'description' => 'The label displayed for the title field on the edit form.', - 'type' => 'varchar', - 'length' => 255, - 'not null' => TRUE, - 'default' => '', - ), - 'has_body' => array( - 'description' => 'Boolean indicating whether this type has the body field attached.', - 'type' => 'int', - 'unsigned' => TRUE, - 'not null' => TRUE, - 'size' => 'tiny', - ), - 'body_label' => array( - 'description' => 'The label displayed for the body field on the edit form.', - 'type' => 'varchar', - 'length' => 255, - 'not null' => TRUE, - 'default' => '', - ), 'custom' => array( 'description' => 'A boolean indicating whether this type is defined by a module (FALSE) or by a user via Add content type (TRUE).', 'type' => 'int', @@ -426,7 +398,7 @@ } /** - * Convert body and teaser from node properties to fields, and migrate status/comment/promote and sticky columns to the {node_revision} table. + * Convert title, body, and teaser from node properties to fields, and migrate status, comment, promote, and sticky columns to the {node_revision} table. */ function node_update_7006(&$context) { $context['#finished'] = 0; @@ -438,10 +410,20 @@ if (!isset($context['total'])) { // Initial invocation. - // Re-save node types to create title and body field instances. + // Create title and body field instances for each node type. foreach ($node_types as $type => $info) { if ($info->has_title || $info->has_body) { - node_type_save($info); + // Add default fields. + node_type_default_fields($info); + // Remove title/body field if it wasn't already there. + if (!$info->has_title) { + $instance = field_info_instance('title', $type); + field_delete_instance($instance); + } + if (!$info->has_body) { + $instance = field_info_instance('body', $type); + field_delete_instance($instance); + } } } @@ -536,9 +518,15 @@ db_drop_field('node_revision', 'teaser'); db_drop_field('node_revision', 'format'); + // Remove node properties that descrbe titles and bodies. + db_drop_field('node_type', 'has_title'); + db_drop_field('node_type', 'title_label'); + db_drop_field('node_type', 'has_body'); + db_drop_field('node_type', 'body_label'); + // We're done. $context['#finished'] = 1; - return t("!number node body and teaser properties migrated to the 'body' field.", array('!number' => $context['total'])); + return t("!number node body and teaser properties migrated to 'title' and 'body' fields.", array('!number' => $context['total'])); } } } Index: modules/node/node.module =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.module,v retrieving revision 1.1145 diff -u -r1.1145 node.module --- modules/node/node.module 11 Oct 2009 03:07:18 -0000 1.1145 +++ modules/node/node.module 12 Oct 2009 06:32:42 -0000 @@ -473,10 +473,6 @@ 'type' => (string) $type->type, 'name' => (string) $type->name, 'base' => (string) $type->base, - 'has_title' => (int) $type->has_title, - 'title_label' => (string) $type->title_label, - 'has_body' => (int) $type->has_body, - 'body_label' => (string) $type->body_label, 'description' => (string) $type->description, 'help' => (string) $type->help, 'custom' => (int) $type->custom, @@ -493,7 +489,6 @@ if (!empty($type->old_type) && $type->old_type != $type->type) { field_attach_rename_bundle($type->old_type, $type->type); } - node_configure_fields($type); module_invoke_all('node_type_update', $type); $status = SAVED_UPDATED; } @@ -504,7 +499,6 @@ ->execute(); field_attach_create_bundle($type->type); - node_configure_fields($type); module_invoke_all('node_type_insert', $type); $status = SAVED_NEW; } @@ -516,106 +510,6 @@ } /** - * Manage the field(s) for a node type. - * - * Currently, the node module manages a single Field API field, - * 'body'. If $type->has_body is true, this function ensures the - * 'body' field exists and creates an instance of it for the bundle - * $type->type (e.g. 'page', 'story', ...). If $type->has_body is - * false, this function removes the instance (if it exists) for the - * 'body' field on $type->type. - */ -function node_configure_fields($type) { - // Add or remove the body field, as needed. - $field = field_info_field('body'); - $instance = field_info_instance('body', $type->type); - if ($type->has_body) { - if (empty($field)) { - $field = array( - 'field_name' => 'body', - 'type' => 'text_with_summary', - ); - $field = field_create_field($field); - } - if (empty($instance)) { - $instance = array( - 'field_name' => 'body', - 'bundle' => $type->type, - 'label' => $type->body_label, - 'widget_type' => 'text_textarea_with_summary', - 'settings' => array('display_summary' => TRUE), - - // Define default formatters for the teaser and full view. - 'display' => array( - 'full' => array( - 'label' => 'hidden', - 'type' => 'text_default', - ), - 'teaser' => array( - 'label' => 'hidden', - 'type' => 'text_summary_or_trimmed', - ), - ), - ); - field_create_instance($instance); - } - else { - $instance['label'] = $type->body_label; - $instance['settings']['display_summary'] = TRUE; - field_update_instance($instance); - } - } - elseif (!empty($instance)) { - field_delete_instance($instance); - } - - if ($type->has_title) { - // Add the title field if not present. - $field = field_info_field('title'); - $instance = field_info_instance('title', $type->type); - - if (empty($field)) { - $field = array( - 'field_name' => 'title', - 'type' => 'text', - ); - $field = field_create_field($field); - } - if (empty($instance)) { - $weight = -5; - $instance = array( - 'field_name' => 'title', - 'bundle' => $type->type, - 'label' => $type->title_label, - 'widget_type' => 'text', - 'widget' => array( - 'weight' => $weight, - ), - 'required' => TRUE, - 'locked' => TRUE, - 'display' => array( - 'full' => array( - 'label' => 'hidden', - 'type' => 'text_default', - 'weight' => $weight, - ), - 'teaser' => array( - 'label' => 'hidden', - 'type' => 'text_default', - 'weight' => $weight, - ), - ), - ); - field_create_instance($instance); - } - else { - $instance['label'] = $type->title_label; - field_update_instance($instance); - } - } -} - -/** * Deletes a node type from the database. * * @param $type @@ -722,10 +616,6 @@ $type->base = ''; $type->description = ''; $type->help = ''; - $type->has_title = 1; - $type->has_body = 1; - $type->title_label = t('Title'); - $type->body_label = t('Body'); $type->custom = 0; $type->modified = 0; $type->locked = 1; @@ -737,19 +627,103 @@ foreach ($info as $key => $data) { $new_type->$key = $data; } - // If the type has no title or body, set an empty label. - if (!$new_type->has_title) { - $new_type->title_label = ''; - } - if (!$new_type->has_body) { - $new_type->body_label = ''; - } $new_type->orig_type = isset($info['type']) ? $info['type'] : ''; return $new_type; } /** + * Create and add instances of default fields to a node type. + * + * @param $type + * A node type object. + * + * @return + * NULL. + * + * If no $type is provided, this will just ensure that the default fields + * (title and body) exist. + */ +function node_type_default_fields($type = NULL) { + // Make sure that the default fields exist. + $field = field_info_field('title'); + if (empty($field)) { + $field = array( + 'field_name' => 'title', + 'type' => 'text', + ); + $field = field_create_field($field); + } + + $field = field_info_field('body'); + if (empty($field)) { + $field = array( + 'field_name' => 'body', + 'type' => 'text_with_summary', + ); + $field = field_create_field($field ); + } + + // Add instances of the default fields to the $type argument. + if (isset($type->type)) { + // Title field instance + $instance = field_info_instance('title', $type->type); + if (empty($instance)) { + $weight = -5; + $instance = array( + 'field_name' => 'title', + 'bundle' => $type->type, + 'label' => t('Title'), + 'widget_type' => 'text', + 'widget' => array( + 'weight' => $weight, + ), + 'required' => TRUE, + 'locked' => TRUE, + 'display' => array( + 'full' => array( + 'label' => 'hidden', + 'type' => 'text_default', + 'weight' => $weight, + ), + 'teaser' => array( + 'label' => 'hidden', + 'type' => 'text_default', + 'weight' => $weight, + ), + ), + ); + field_create_instance($instance); + } + + // Body field instance + $instance = field_info_instance('body', $type->type); + if (empty($instance)) { + $instance = array( + 'field_name' => 'body', + 'bundle' => $type->type, + 'label' => t('Body'), + 'widget_type' => 'text_textarea_with_summary', + 'settings' => array('display_summary' => TRUE), + + // Define default formatters for the teaser and full view. + 'display' => array( + 'full' => array( + 'label' => 'hidden', + 'type' => 'text_default', + ), + 'teaser' => array( + 'label' => 'hidden', + 'type' => 'text_summary_or_trimmed', + ), + ), + ); + field_create_instance($instance); + } + } +} + +/** * Determine whether a node hook exists. * * @param $node Index: profiles/default/default.install =================================================================== RCS file: /cvs/drupal/drupal/profiles/default/default.install,v retrieving revision 1.9 diff -u -r1.9 default.install --- profiles/default/default.install 8 Oct 2009 07:58:47 -0000 1.9 +++ profiles/default/default.install 12 Oct 2009 06:32:43 -0000 @@ -144,6 +144,7 @@ foreach ($types as $type) { $type = node_type_set_defaults($type); node_type_save($type); + node_type_default_fields($type); } // Default page to not be promoted and have comments disabled.