Index: title.info
===================================================================
RCS file: /cvs/drupal/contributions/modules/title/title.info,v
retrieving revision 1.2
diff -u -r1.2 title.info
--- title.info	11 Oct 2010 19:59:57 -0000	1.2
+++ title.info	27 Oct 2010 12:07:02 -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 the node title with a normal field.
 core = 7.x
-dependencies[] = locale
 files[] = title.module
 files[] = tests/title.test
Index: title.install
===================================================================
RCS file: /cvs/drupal/contributions/modules/title/title.install,v
retrieving revision 1.1
diff -u -r1.1 title.install
--- title.install	11 Oct 2010 19:56:17 -0000	1.1
+++ title.install	27 Oct 2010 12:07:02 -0000
@@ -6,3 +6,39 @@
  * 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_query("UPDATE {system} SET weight = -100 WHERE name = 'title'");
+}
+
+/**
+ * Implements hook_uninstall().
+ */
+function title_uninstall() {
+  db_delete('variable')->condition('name', 'title_field_enabled_%', 'LIKE')->execute();
+}
Index: title.module
===================================================================
RCS file: /cvs/drupal/contributions/modules/title/title.module,v
retrieving revision 1.19
diff -u -r1.19 title.module
--- title.module	11 Oct 2010 19:56:17 -0000	1.19
+++ title.module	27 Oct 2010 12:07:03 -0000
@@ -6,3 +6,227 @@
  * Translatable entity title/label functionality.
  */
 
+/**
+ * Implements hook_field_info().
+ */
+function title_field_info() {
+  return array(
+    'title_field' => 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_field';
+}
+
+/**
+ * Implements hook_field_is_empty().
+ */
+function title_field_is_empty($item, $field) {
+  return empty($item['value']);
+}
+
+/**
+ * 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_enabled($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;
+}
+
+/**
+ * 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_enabled($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'];
+    }
+  }
+}
+
+/**
+ * Implements hook_field_presave().
+ */
+function title_field_presave($entity_type, $entity, $field, $instance, $langcode, &$items) {
+  title_field_sync($entity_type, $entity, FALSE);
+}
+
+/**
+ * Check if the title field is enabled for a bundle.
+ *
+ * @param string $bundle
+ *   The name of the bundle.
+ *
+ * @return boolean
+ */
+function title_field_enabled($bundle) {
+  return variable_get('title_field_enabled_' . $bundle, FALSE);
+}
+
+/**
+ * Implements hook_field_attach_create_bundle().
+ *
+ * Make sure that new bundles, with title translation enabled, have the
+ * title_field instance.
+ *
+ * @param string $entity_type
+ *   The name of the entity type.
+ * @param string $bundle
+ *   The name of the bundle.
+ */
+function title_field_attach_create_bundle($entity_type, $bundle) {
+  title_configure_bundle($entity_type, $bundle);
+}
+
+/**
+ * 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_enabled($bundle->type)) {
+      unset($info['node'][$bundle->type]['form']['title']);
+    }
+  }
+}
+
+/**
+ * Implements hook_form_FORM_ID_alter().
+ *
+ * Provide settings into the node content type form to enable
+ * title field.
+ */
+function title_form_node_type_form_alter(&$form, &$form_state) {
+  // Checkbox to enable/disable title field.
+  $form['submission']['title_field_enabled'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Enable title field'),
+    '#description' => t('Store title as a common instead an extra field.'),
+    '#default_value' => variable_get('title_field_enabled_' . $form['#node_type']->type, FALSE),
+  );
+  // 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);
+}
+
+/**
+ * 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_field',
+        '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);
+
+  $state = title_field_enabled($bundle);
+  switch (TRUE) {
+    // Enable translatable title.
+    case $state && !$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);
+      break;
+
+      // Disable translatable title.
+    case !$state && $instance:
+      field_delete_instance($instance);
+      break;
+  }
+}
+
+/**
+ * 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_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);
+    }
+  }
+}
