Index: title.info
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/title/title.info,v
retrieving revision 1.2
diff -u -p -r1.2 title.info
--- title.info	11 Oct 2010 19:59:57 -0000	1.2
+++ title.info	12 Nov 2010 19:18:56 -0000
@@ -1,8 +1,6 @@
 ; $Id: title.info,v 1.2 2010/10/11 19:59:57 sun Exp $
 name = Title
-description = Allows entity titles/labels to be translated.
-package = Multilingual
+description = Replaces entity labels with fields.
 core = 7.x
-dependencies[] = locale
 files[] = title.module
 files[] = tests/title.test
Index: title.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/title/title.install,v
retrieving revision 1.1
diff -u -p -r1.1 title.install
--- title.install	11 Oct 2010 19:56:17 -0000	1.1
+++ title.install	12 Nov 2010 19:04:27 -0000
@@ -6,3 +6,44 @@
  * Installation functions for Title module.
  */
 
+/**
+ * Implements hook_field_schema().
+ */
+function title_field_schema() {
+  $columns = array(
+    'value' => array(
+      'description' => 'A field replacing node title.',
+      'type' => 'varchar',
+      'length' => 255,
+      'default' => '',
+      'not null' => TRUE,
+    ),
+  );
+
+  return array(
+    'columns' => $columns,
+    'indexes' => array(
+      'title' => array('value'),
+    ),
+  );
+}
+
+
+/**
+ * Implements hook_install().
+ */
+function title_install() {
+  // Make sure the title is properly handled before any other module
+  // access it.
+  db_update('system')
+    ->fields(array('weight' => -100))
+    ->condition('name', 'title')
+    ->execute();
+}
+
+/**
+ * Implements hook_uninstall().
+ */
+function title_uninstall() {
+  db_delete('variable')->condition('name', 'title_field_enabled_%', 'LIKE')->execute();
+}
Index: title.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/title/title.module,v
retrieving revision 1.19
diff -u -p -r1.19 title.module
--- title.module	11 Oct 2010 19:56:17 -0000	1.19
+++ title.module	12 Nov 2010 19:32:59 -0000
@@ -3,6 +3,228 @@
 
 /**
  * @file
- * Translatable entity title/label functionality.
+ * Replaces entity labels with fields.
  */
 
+/**
+ * Implements hook_field_info().
+ */
+function title_field_info() {
+  return array(
+    'title' => array(
+      'label' => t('Title'),
+      'description' => t('A field replacing node title.'),
+      'default_widget' => 'text_textfield',
+      'default_formatter' => 'text_default',
+      'no_ui' => TRUE,
+      'settings' => array(
+        'max_length' => '255',
+      ),
+    ),
+  );
+}
+
+/**
+ * Implements hook_field_widget_info().
+ */
+function title_field_widget_info_alter(&$info) {
+  $info['text_textfield']['field types'][] = 'title';
+}
+
+/**
+ * Implements hook_field_load().
+ *
+ * @see title_entity_load()
+ */
+function title_field_load($entity_type, $entities, $field, $instances, $langcode, &$items, $age) {
+  title_entity_load($entities, $entity_type);
+}
+
+/**
+ * Implements hook_field_is_empty().
+ */
+function title_field_is_empty($item, $field) {
+  return !isset($item['value']) || $item['value'] === '';
+}
+
+/**
+ * Implements hook_field_presave().
+ */
+function title_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
+  title_field_sync($entity_type, $entity, FALSE);
+}
+
+/**
+ * Implements hook_field_extra_fields_alter().
+ */
+function title_field_extra_fields_alter(&$info) {
+  // Remove node title if title field is enabled.
+  foreach (node_type_get_types() as $bundle) {
+    if (isset($info['node'][$bundle->type]['form']['title']) && title_field_is_enabled('node', $bundle->type)) {
+      unset($info['node'][$bundle->type]['form']['title']);
+    }
+  }
+}
+
+/**
+ * Implements hook_field_attach_create_bundle().
+ *
+ * Make sure that new field bundles having title translation enabled contain a
+ * title_field field instance.
+ */
+function title_field_attach_create_bundle($entity_type, $bundle) {
+  title_configure_bundle($entity_type, $bundle);
+}
+
+/**
+ * API function to sync the node title.
+ *
+ * @param string $entity_type
+ *   The name of the entity type.
+ * @param object $entity
+ *   The entity to work with.
+ * @param boolean $display
+ *   Specifies if the display- or the node-language is used.
+ */
+function title_field_sync($entity_type, &$entity, $display = TRUE) {
+  if (isset($entity->title) && title_field_is_enabled('node', $entity->type)) {
+    // Choose the appropriate language.
+    $langcode = ($display ? field_language($entity_type, $entity, 'title_field') : $entity->language);
+
+    if (isset($entity->title_field[$langcode][0]['value'])) {
+      $entity->title = $entity->title_field[$langcode][0]['value'];
+    }
+  }
+}
+
+/**
+ * Enables/disables the title_field on a bundle.
+ *
+ * @param string $entity_type
+ *   The name of the entity type.
+ * @param string $bundle
+ *   The name of the bundle.
+ */
+function title_configure_bundle($entity_type, $bundle) {
+  // Make sure there is such a field to create a instance of.
+  $field = field_read_field('title_field');
+  if (empty($field)) {
+    $field = array(
+        'field_name' => 'title_field',
+        'type' => 'title',
+        'cardinality' => 1,
+        'translatable' => TRUE,
+        'locked' => TRUE,
+    );
+    $field = field_create_field($field);
+  }
+  $field_type_info = field_info_field_types('title_field');
+  $instance = field_info_instance($entity_type, 'title_field', $bundle);
+  $enabled = title_field_is_enabled('node', $bundle);
+
+  // Create a title_field field instance.
+  if ($enabled && !$instance) {
+    $instance = array(
+      'label' => t('Title'),
+      'description' => $field_type_info['description'],
+      'required' => TRUE,
+      'locked' => TRUE,
+      'field_name' => 'title_field',
+      'entity_type' => $entity_type,
+      'bundle' => $bundle,
+      'settings' => array(
+        'text_processing' => 0,
+      ),
+      'widget' => array(
+        'weight' => -5,
+      ),
+    );
+    field_create_instance($instance);
+  }
+  // Delete the title_field field instance.
+  elseif (!$enabled && $instance) {
+    field_delete_instance($instance);
+  }
+}
+
+/**
+ * Check if the title field is enabled for a bundle.
+ *
+ * @param $entity_type
+ *   The type of the entity.
+ * @param $bundle
+ *   The name of the bundle.
+ *
+ * @return boolean
+ */
+function title_field_is_enabled($entity_type, $bundle) {
+  return variable_get('title_field_enabled_' . $entity_type . '_' . $bundle, FALSE);
+}
+
+/**
+ * Implements hook_entity_load().
+ *
+ * Since the result of field_attach_load() is cached, we perform title
+ * synchronization also here to ensure that we always have the correct
+ * value in $entity->title.
+ */
+function title_entity_load($entities, $type) {
+  if ($type == 'node') {
+    foreach ($entities as &$entity) {
+      title_field_sync($type, $entity);
+    }
+  }
+}
+
+/**
+ * Implements hook_form_FORM_ID_alter().
+ *
+ * Provide settings into the node content type form to enable
+ * title field.
+ *
+ * @todo Move this into Field UI's Manage Fields form.
+ */
+function title_form_node_type_form_alter(&$form, &$form_state) {
+  // Checkbox to enable/disable title field.
+  $status = variable_get('title_field_enabled_node_' . $form['#node_type']->type, FALSE);
+  $form['submission']['title_field_enabled_node'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Store title as a field'),
+    '#default_value' => $status,
+    '#weight' => 0,
+    // Once enabled, disabling would mean potential data loss.
+    '#disabled' => $status,
+  );
+  // Add handler to manage the field instance.
+  $form['#submit'][] = 'title_form_node_type_form_submit';
+}
+
+/**
+ * Submit handler to add/remove title_field instance to a bundle.
+ */
+function title_form_node_type_form_submit(&$form, &$form_state) {
+  title_configure_bundle('node', $form['#node_type']->type);
+}
+
+/**
+ * Implements hook_form_FORM_ID_alter().
+ *
+ * Add a submit handler to node forms and hide the standard title field.
+ */
+function title_form_node_form_alter(&$form, &$form_state, $form_id) {
+  $bundle = $form['#node']->type;
+  if (title_field_is_enabled('node', $bundle)) {
+    array_unshift($form['#submit'], 'title_node_form_submit');
+    $form['title']['#access'] = FALSE;
+  }
+}
+
+/**
+ * Submit handler for node forms.
+ */
+function title_node_form_submit($form, &$form_state) {
+  $values = (object) $form_state['values'];
+  title_field_sync($form['#entity_type'], $values, FALSE);
+  $form_state['values'] = (array) $values;
+}
+
