diff --git a/content.module b/content.module
index ce3628e..bc2c84c 100644
--- a/content.module
+++ b/content.module
@@ -1132,6 +1132,23 @@ function content_database_info($field) {
 }
 
 /**
+ * Helper function for identifying the storage type for a field.
+ */
+function content_storage_type($field) {
+  if ($field['multiple'] > 0) {
+    return CONTENT_DB_STORAGE_PER_FIELD;
+  }
+  else {
+    require_once drupal_get_path('module', 'content') ."/content_crud.inc";
+    $instances = content_field_instance_read(array('field_name' => $field['field_name']));
+    if (count($instances) > 1) {
+      return CONTENT_DB_STORAGE_PER_FIELD;
+    }
+  }
+  return CONTENT_DB_STORAGE_PER_CONTENT_TYPE;
+}
+
+/**
  * Manipulate a 2D array to reverse rows and columns.
  *
  * The default data storage for fields is delta first, column names second.
diff --git a/content_admin.inc b/content_admin.inc
index 4d63e15..74de648 100644
--- a/content_admin.inc
+++ b/content_admin.inc
@@ -575,35 +575,12 @@ function theme_content_admin_field_add_new_field_widget_type($form) {
  * Add an existing field to a content type.
  */
 function _content_admin_field_add_existing_submit($form_id, $form_values) {
+  require_once './'. drupal_get_path('module', 'content') .'/content_crud.inc';
   $type  = content_types($form_values['type_name']);
-  $field = content_fields($form_values['field_name']);
-  $field_types = _content_field_types();
-  $field_type = $field_types[$field['type']];
-  $columns = module_invoke($field_type['module'], 'field_settings', 'database columns', $field);
-
-  if (is_array($columns) && count($columns)) {
-    if ($field['db_storage'] == CONTENT_DB_STORAGE_PER_CONTENT_TYPE) {
-      $new_field = $field;
-      $new_field['db_storage'] = CONTENT_DB_STORAGE_PER_FIELD;
-      db_query("UPDATE {node_field} SET db_storage = %d WHERE field_name = '%s'", CONTENT_DB_STORAGE_PER_FIELD, $form_values['field_name']);
-      content_alter_db_field($field, $columns, $new_field, $columns);
-    }
-  }
 
-  $prior_instance = db_fetch_array(db_query("SELECT * FROM {node_field_instance} WHERE field_name = '%s'", $form_values['field_name']));
-  if (!$prior_instance) {
-    $prior_instance = array();
-    $prior_instance['weight'] = 0;
-    $prior_instance['label'] = $form_values['field_name'];
-    $prior_instance['widget_type'] = '';
-    $prior_instance['widget_settings'] = '';
-    $prior_instance['display_settings'] = '';
-    $prior_instance['description'] = '';
-  }
-  db_query("INSERT INTO {node_field_instance} (field_name, type_name, weight, label, widget_type, widget_settings, display_settings, description) VALUES ('%s', '%s', %d, '%s', '%s', '%s', '%s', '%s')", $form_values['field_name'], $form_values['type_name'], $prior_instance['weight'], $prior_instance['label'], $prior_instance['widget_type'], $prior_instance['widget_settings'], $prior_instance['display_settings'], $prior_instance['description']);
+  content_field_instance_create($form_values);
 
   drupal_set_message(t('Added field %label.', array('%label' => $prior_instance['label'])));
-  content_clear_type_cache();
   return 'admin/content/types/'. $type['url_str'] .'/fields';
 }
 
@@ -628,16 +605,14 @@ function _content_admin_field_add_new_validate($form_id, $form_values) {
  * Create a new field for a content type.
  */
 function _content_admin_field_add_new_submit($form_id, $form_values) {
-  // Find a valid, computer-friendly field name.
-
-  $fields = content_fields();
+  require_once './'. drupal_get_path('module', 'content') .'/content_crud.inc';
   $type   = content_types($form_values['type_name']);
-
-  // Accept field name from programmed submissions if valid and it doesn't already exist.
-  if ($form_values['field_name']) {
-    $field_name = $form_values['field_name'];
-  }
-  else {
+  $field = array(
+    'field_name' => $form_values['field_name'],
+    'label' => $form_values['label'],
+    'type_name' => $form_values['type_name'],
+  );
+  if (empty($form_values['field_name'])) {
     $field_name = trim($form_values['label']);
     $field_name = drupal_strtolower($field_name);
     $field_name = str_replace(array(' ', '-'), '_', $field_name);
@@ -651,24 +626,15 @@ function _content_admin_field_add_new_submit($form_id, $form_values) {
       }   while (isset($fields[$new_name]));
       $field_name = $new_name;
     }
+    $field['field_name'] = $field_name;
   }
+  $widget = explode('-', $form_values['field_widget_type']);
+  $field['type'] = $widget[0];
+  $field['widget_type'] = $widget[1];
 
-  $field_widget_type = explode('-', $form_values['field_widget_type']);
-  db_query("INSERT INTO {node_field} (field_name, type, global_settings, required, multiple, db_storage) VALUES ('%s', '%s', '%s', %d, %d, %d)", $field_name, $field_widget_type[0], serialize(array()), 0, 0, CONTENT_DB_STORAGE_PER_CONTENT_TYPE);
-  db_query("INSERT INTO {node_field_instance} (field_name, type_name, weight, label, widget_type, widget_settings, display_settings, description) VALUES ('%s', '%s', %d, '%s', '%s', '%s', '%s', '%s')", $field_name, $form_values['type_name'], 0, $form_values['label'], $field_widget_type[1], serialize(array()), serialize(array()), '');
-
+  content_field_instance_create($field);
   content_clear_type_cache();
 
-  // Create new database columns as necessary.
-  $field_types = _content_field_types();
-  $field_type = $field_types[$field_widget_type[0]];
-  $field = content_fields($field_name);
-
-  $columns = module_invoke($field_type['module'], 'field_settings', 'database columns', $field);
-  if (is_array($columns) && count($columns)) {
-    content_alter_db_field(array(), array(), $field, $columns);
-  }
-
   drupal_set_message(t('Created field %label.', array('%label' => $form_values['label'])));
   return 'admin/content/types/'. $type['url_str'] .'/fields/'. $field_name;
 }
@@ -710,7 +676,7 @@ function _content_admin_field_remove_submit($form_id, $form_values) {
 
   if ($type && $field && $form_values['confirm']) {
     include_once('./'. drupal_get_path('module', 'content') .'/content_crud.inc');
-    content_field_instance_delete($form_values);
+    content_field_instance_delete($field['field_name'], $field['type_name']);
 
     drupal_set_message(t('Removed field %field from %type.', array('%field' => $field['widget']['label'], '%type' => $type['name'])));
     content_clear_type_cache();
@@ -973,67 +939,45 @@ function _content_admin_field_validate($form_id, $form_values, $form) {
  * Save a field's settings after editing.
  */
 function _content_admin_field_submit($form_id, $form_values) {
+  require_once './'. drupal_get_path('module', 'content') .'/content_crud.inc';
   $type = content_types($form_values['type_name']);
-  $field = $type['fields'][$form_values['field_name']];
-  $field_types = _content_field_types();
-  $field_type = $field_types[$field['type']];
-  $widget_types = _content_widget_types();
-  $widget_type = $widget_types[$form_values['widget_type']];
-
-  // If content.module is handling the default value,
-  // initialize $widget_settings with default values,
-  if (content_handle('widget', 'default value', $field) == CONTENT_CALLBACK_DEFAULT) {
-    $widget_settings = array(
-      'default_value' => $form_values['default_value'],
-      'default_value_php' => $form_values['default_value_php'],
-      );
-  }
-
-  $setting_names = module_invoke($widget_type['module'], 'widget_settings', 'save', $field);
-  if (is_array($setting_names)) {
-    foreach ($setting_names as $setting) {
-      $widget_settings[$setting] = $form_values[$setting];
-    }
-  }
-  $field_settings = array();
-  $setting_names = module_invoke($field_type['module'], 'field_settings', 'save', $field);
-  if (is_array($setting_names)) {
-    foreach ($setting_names as $setting) {
-      $field_settings[$setting] = $form_values[$setting];
-    }
-  }
 
-  $prev_field = $field;
-  $prev_columns = module_invoke($field_type['module'], 'field_settings', 'database columns', $field);
+  content_field_instance_update($form_values);
 
-  db_query("UPDATE {node_field_instance} SET weight = %d, label = '%s', widget_type = '%s', widget_settings = '%s', description = '%s' WHERE type_name = '%s' AND field_name = '%s'", $form_values['weight'], $form_values['label'], $form_values['widget_type'], serialize($widget_settings), $form_values['description'], $form_values['type_name'], $form_values['field_name']);
+  drupal_set_message(t('Saved field %field.', array('%field' => $form_values['label'])));
+  return 'admin/content/types/'. $type['url_str'] .'/fields';
+}
 
-  if ($form_values['multiple']) {
-    $field['db_storage'] = CONTENT_DB_STORAGE_PER_FIELD;
+/**
+ * Content Schema Alter
+ *
+ * Alter the database schema.
+ *
+ * TODO figure out an API-safe way to use batching to update the nodes that
+ * will be affected by this change so the node_save() hooks will fire.
+ *
+ */
+function content_alter_schema($previous_field, $new_field) {
+  $type = !empty($new_field) ? $new_field['type'] : $previous_field['type'];
+  $field_types = _content_field_types();
+  $field_type = $field_types[$type];
+  if (empty($previous_field)) {
+    $previous_columns = array();
   }
   else {
-    $instances = db_result(db_query("SELECT COUNT(*) FROM {node_field_instance} WHERE field_name = '%s'", $form_values['field_name']));
-    if ($instances == 1) {
-      $field['db_storage'] = CONTENT_DB_STORAGE_PER_CONTENT_TYPE;
-    }
+    $previous_columns = module_invoke($field_type['module'], 'field_settings', 'database columns', $previous_field);
   }
-  db_query("UPDATE {node_field} SET required = %d, multiple = %d, global_settings = '%s', db_storage = %d WHERE field_name = '%s'", $form_values['required'], $form_values['multiple'], serialize($field_settings), $field['db_storage'], $form_values['field_name']);
 
-  drupal_set_message(t('Saved field %field.', array('%field' => $form_values['label'])));
   content_clear_type_cache();
 
-  $new_field = content_fields($form_values['field_name']);
-  $new_columns = module_invoke($field_type['module'], 'field_settings', 'database columns', $new_field);
-
-  if (!isset($prev_columns)) {
-    $prev_columns = array();
-  }
-  if (!isset($new_columns)) {
+  if (empty($new_field)) {
     $new_columns = array();
   }
-  content_alter_db_field($prev_field, $prev_columns, $new_field, $new_columns);
+  else {
+    $new_columns = module_invoke($field_type['module'], 'field_settings', 'database columns', $new_field);
+  }
 
-  return 'admin/content/types/'. $type['url_str'] .'/fields';
+  content_alter_db_field($previous_field, $previous_columns, $new_field, $new_columns);
 }
 
 /**
@@ -1474,4 +1418,4 @@ function content_db_change_column($table, $column, $column_new, $type, $attribut
       db_query('ALTER TABLE {'. $table .'} CHANGE '. $column .' '. $column_new .' '. $type .' '. $not_null .' '. $default);
       break;
   }
-}
\ No newline at end of file
+}
diff --git a/content_crud.inc b/content_crud.inc
index d23a571..edfdc9b 100644
--- a/content_crud.inc
+++ b/content_crud.inc
@@ -4,267 +4,625 @@
 /**
  * @file
  * Create/Read/Update/Delete functions for CCK-defined object types.
+ *
+ * The content module field API will allow $field arguments to
+ * be input either in the field => widget nested array that is used
+ * by the content module, or in flattened $form_values arrays, by
+ * converting flattened arrays to the nested format.
+ *
+ * A hook_content_fieldapi() is available for each field instance action,
+ * and each hook receives the nested field => widget array as an argument.
+ *
+ * The hook_content_fieldapi() $ops include:
+ *
+ *   - create instance
+ *   - read instance
+ *   - update instance
+ *   - delete instance
+ *
+ * Another function, content_module_delete($module) will clean up
+ * after a module that has been deleted by removing all data and
+ * settings information that was created by that module.
  */
 
 /**
- * Rebuild content type information from node tables.
- *
- *  Used to update CCK tables that might have missed changes made when CCK was disabled.
- *  Called by hook_form_alter() on system modules page whenever CCK is enabled.
+ * Create an array of default values for a field type.
  */
-function content_types_rebuild() {
-  $db_types = content_types();
+function content_field_default_values($field_type) {
+  $field_types = _content_field_types();
+  $module = $field_types[$field_type]['module'];
+
+  $field = array(
+    'module' => $module,
+    'type' => $field_type,
+    'active' => 0,
+  );
 
-  $result = db_query("SELECT type_name FROM {node_field_instance}");
-  while ($type = db_fetch_array($result)) {
-    $field_types[] = $type['type_name'];
+  if (module_exists($module)) {
+    $field['active'] = 1;
   }
 
-  foreach ($db_types as $content_type) {
-    // Find content types that are missing the content table and add it
-    content_type_create((object)array('type' => $content_type['type']));
+  $field['columns'] = module_invoke($module, 'field_settings', 'database columns', $field);
+  // Ensure columns always default to NULL values.
+  foreach ((array) $field['columns'] as $column_name => $column) {
+    $field['columns'][$column_name]['not null'] = FALSE;
   }
-  content_clear_type_cache();
-}
 
-/**
- * Make changes needed when a content type is created.
- *
- * @param $info
- *   value supplied by hook_node_type()
- */
-function content_type_create($info) {
-  content_clear_type_cache();
-  $type = content_types($info->type);
-  $table = _content_tablename($type['type'], CONTENT_DB_STORAGE_PER_CONTENT_TYPE);
-  if (!db_table_exists($table)) {
-    switch ($GLOBALS['db_type']) {
-      case 'mysql':
-      case 'mysqli':
-        db_query("CREATE TABLE {". $table ."} (
-          vid int unsigned NOT NULL default '0',
-          nid int unsigned NOT NULL default '0',
-          PRIMARY KEY (vid)
-        ) /*!40100 DEFAULT CHARACTER SET utf8 */");
-      break;
+  $field['required'] = 0;
+  $field['multiple'] = 0;
+  $field['db_storage'] = CONTENT_DB_STORAGE_PER_CONTENT_TYPE;
 
-      case 'pgsql':
-        db_query("CREATE TABLE {". $table ."} (
-          vid int_unsigned NOT NULL default '0',
-          nid int_unsigned NOT NULL default '0',
-          PRIMARY KEY (vid)
-        )");
-      break;
+  // Make sure field settings all have an index in the array.
+  $setting_names = module_invoke($module, 'field_settings', 'save', $field);
+  if (is_array($setting_names)) {
+    foreach ($setting_names as $setting) {
+      $field[$setting] = NULL;
     }
-    drupal_set_message(t('The content fields table %name has been created.', array('%name' => $table)));
   }
+  return $field;
 }
 
 /**
- * Make changes needed when an existing content type is updated.
- *
- * @param $info
- *   value supplied by hook_node_type()
+ * Create an array of default values for a field instance.
  */
-function content_type_update($info) {
-  if (!empty($info->old_type) && $info->old_type != $info->type) {
-    // rename the content type in all fields that use changed content type.
-    db_query("UPDATE {node_field_instance} SET type_name='%s' WHERE type_name='%s'", array($info->type, $info->old_type));
+function content_instance_default_values($field_name, $type_name, $widget_type) {
+  $widget_types = _content_widget_types();
+  $module = $widget_types[$widget_type]['module'];
 
-    // Rename the content fields table to match new content type name.
-    $old_type = content_types($info->old_type);
-    $old_name = _content_tablename($old_type['type'], CONTENT_DB_STORAGE_PER_CONTENT_TYPE);
-    $new_name = _content_tablename($info->type, CONTENT_DB_STORAGE_PER_CONTENT_TYPE);
-    if (db_table_exists($old_name)) {
-      switch ($GLOBALS['db_type']) {
-        case 'mysql':
-        case 'mysqli':
-          db_query("RENAME TABLE {". $old_name ."} TO {". $new_name ."}");
-          break;
-
-        case 'pgsql':
-          db_query("ALTER TABLE {". $old_name ."} RENAME TO {". $new_name ."}");
-          break;
-      }
-      drupal_set_message(t('Content fields table %old_name has been renamed to %new_name and field instances have been updated.', array('%old_name' => $old_name, '%new_name' => $new_name)));
-    }
+  $widget = array(
+    'field_name' => $field_name,
+    'type_name' => $type_name,
+    'weight' => 0,
+    'label' => $field_name,
+    'description' => '',
+    'widget_type' => $widget_type,
+    'widget_module' => $module,
+    'display_settings' => array(),
+    'widget_settings' => array(),
+  );
+
+  if (module_exists($module)) {
+    $widget['widget_active'] = 1;
   }
-  // reset all content type info
-  content_clear_type_cache();
+
+  $settings_names = array_merge(array('label'), array_keys(_content_admin_display_contexts()));
+  $widget['display_settings'] = array();
+  foreach ($settings_names as $name) {
+    $widget['display_settings'][$name]['format'] = ($name == 'label') ? 'above' : 'default';
+  }
+
+  // Make sure widget settings all have an index in the array.
+  $settings_names = module_invoke($module, 'widget_settings', 'save', $widget);
+  $widget['widget_settings'] = array();
+  foreach ((array) $settings_names as $name) {
+    $widget['widget_settings'][$name] = NULL;
+  }
+  return $widget;
 }
 
 /**
- * Make changes needed when a content type is deleted.
- *
- * @param $info
- *   value supplied by hook_node_type()
+ * Expand field info to create field => widget info.
  */
-function content_type_delete($info) {
-  $type = content_types($info->type);
+function content_field_instance_expand($field) {
+  if (isset($field['widget'])) {
+    return $field;
+  }
+  $field['widget'] = !empty($field['widget_settings']) ? $field['widget_settings'] : array();
+  $field['widget']['label'] = !empty($field['label']) ? $field['label'] : $field['field_name'];
+  $field['widget']['weight'] = !empty($field['weight']) ? $field['weight'] : NULL;
+  $field['widget']['description'] = !empty($field['description']) ? $field['description'] : NULL;
 
-  foreach ($type['fields'] as $field) {
-    content_field_instance_delete(array('type_name' => $info->type, 'field_name' => $field['field_name']));
+  if (!empty($field['widget_type'])) {
+    $field['widget']['type'] = $field['widget_type'];
+    $widget_types = _content_widget_types();
+    $field['widget']['module'] = $widget_types[$field['widget_type']]['module'];
   }
-  $table = _content_tablename($type['type'], CONTENT_DB_STORAGE_PER_CONTENT_TYPE);
-  if (db_table_exists($table)) {
-    db_query('DROP TABLE {'. $table .'}');
-    drupal_set_message(t('The content fields table %name has been deleted.', array('%name' => $table)));
+  elseif (!empty($field['widget_module'])) {
+    $field['widget']['module'] = $field['widget_module'];
   }
 
-  // reset all content type info
-  content_clear_type_cache();
-}
+  unset($field['widget_type']);
+  unset($field['weight']);
+  unset($field['label']);
+  unset($field['description']);
+  unset($field['widget_module']);
+  unset($field['widget_settings']);
 
+  // If content.module is handling the default value,
+  // initialize $widget_settings with default values,
+  if (isset($field['default_value']) && isset($field['default_value_php']) &&
+      content_handle('widget', 'default value', $field) == CONTENT_CALLBACK_DEFAULT) {
+    $field['widget']['default_value'] = !empty($field['default_value']) ? $field['default_value']  : NULL;
+    $field['widget']['default_value_php'] = !empty($field['default_value_php']) ? $field['default_value_php'] : NULL;
+    unset($field['default_value']);
+    unset($field['default_value_php']);
+  }
+  return $field;
+}
 
 /**
- * Create a new field.
- *
- * Any call to this function *must* be immediately followed by a call to
- * content_field_instance_create(), or the database could be left in an
- * inconsistent state.
- *
- * @param $properties
- *   An array of properties to load the field with. Valid keys:
- *   - '' -
- * @return
- *   The ID of the newly-created field.
+ * Collapse field info from field => widget to flattened form values.
  */
-function content_field_create($properties) {
-  // TODO
+function content_field_instance_collapse($field) {
+  if (!isset($field['widget'])) {
+    return $field;
+  }
+  $field['widget_settings'] = !empty($field['widget']) ? $field['widget'] : array();
+  $field['widget_type'] = !empty($field['widget']['type']) ? $field['widget']['type'] : '';
+  $field['weight'] = !empty($field['widget']['weight']) ? $field['widget']['weight'] : 0;
+  $field['label'] = !empty($field['widget']['label']) ? $field['widget']['label'] : $field['field_name'];
+  $field['description'] = !empty($field['widget']['description']) ? $field['widget']['description'] : '';
+  $field['type_name'] = !empty($field['type_name']) ? $field['type_name'] : '';
+
+  if (!empty($field['widget']['module'])) {
+    $widget_module = $field['widget']['module'];
+  }
+  elseif (!empty($field['widget']['type'])) {
+    $widget_types = _content_widget_types();
+    $widget_module = $widget_types[$field['widget']['type']]['module'];
+  }
+  else {
+    $widget_module = '';
+  }
+  $field['widget_module'] = $widget_module;
+  unset($field['widget_settings']['type']);
+  unset($field['widget_settings']['weight']);
+  unset($field['widget_settings']['label']);
+  unset($field['widget_settings']['description']);
+  unset($field['widget_settings']['module']);
+  unset($field['widget']);
+  return $field;
 }
 
 /**
- * Load a field.
+ * Create a new field instance.
  *
- * @param $properties
- *   An array of properties to use in selecting a field. Valid keys:
- *   - '' -
- * @return
- *   The field array.
+ * @param $field
+ *   An array of properties to create the field with, input either in
+ *   the field => widget format used by the content module or as an
+ *   array of form values.
+ *
+ *   Required values:
+ *   - field_name, the name of the field to be created
+ *   - type_name, the content type of the instance to be created
+ *
+ *   If there is no prior instance to create this from, we also need:
+ *   - type, the type of field to create
+ *   - widget_type, the type of widget to use
  */
-function content_field_read($properties) {
-  // TODO
+function content_field_instance_create($field) {
+  include_once('./'. drupal_get_path('module', 'content') .'/content_admin.inc');
+
+  $form_values = $field;
+  $field = content_field_instance_expand($field);
+
+  // If there are prior instances, fill out missing values from the prior values,
+  // otherwise get missing values from default values.
+  $prior_instances = content_field_instance_read(array('field_name' => $field['field_name']));
+  if (!empty($prior_instances) && is_array($prior_instances)) {
+    $prev_field = content_field_instance_expand($prior_instances[0]);
+
+    // Weight, label, and description may have been forced into the $field
+    // by content_field_instance_expand(). If there is a previous instance to
+    // get these values from and there was no value supplied originally, use
+    // the previous value.
+    $field['widget']['weight'] = isset($form_values['weight']) ? $form_values['weight'] : $prev_field['widget']['weight'];
+    $field['widget']['label']  = isset($form_values['label']) ? $form_values['label'] : $prev_field['widget']['label'];
+    $field['widget']['description'] = isset($form_values['description']) ? $form_values['description'] : $prev_field['widget']['description'];
+  }
+  else {
+    $prev_field = array('widget' => array());
+  }
+
+  // If we have a field type, we can build default values for this field type.
+  $default_values = array('widget' => array());
+  if (isset($field['type'])) {
+    $default_values = content_field_default_values($field['type']);
+    $default_instance_values = content_instance_default_values($field['field_name'], $field['type_name'], $field['widget']['type']);
+    $default_values = content_field_instance_expand(array_merge($default_values, $default_instance_values));
+  }
+
+  // Merge default values, previous values, and current values to create
+  // a complete field array.
+  $widget = array_merge($default_values['widget'], $prev_field['widget'], $field['widget']);
+  $field = array_merge($default_values, $prev_field, $field);
+  $field['widget'] = $widget;
+
+  // Make sure we know what module to invoke for field info.
+  if (empty($field['module']) && !empty($field['type'])) {
+    $field_types = _content_field_types();
+    $field['module'] = $field_types[$field['type']]['module'];
+  }
+
+  // The storage type may need to be updated.
+  $field['db_storage'] = content_storage_type($field);
+
+  // Get a fresh copy of the column information whenever a field is created.
+  $field['columns'] = (array) module_invoke($field['module'], 'field_settings', 'database columns', $field);
+
+  if (empty($prev_field['widget']) || $prior_instances < 1) {
+    // If this is the first instance, create the field.
+    $field['db_storage'] = $field['multiple'] > 0 ? CONTENT_DB_STORAGE_PER_FIELD : CONTENT_DB_STORAGE_PER_CONTENT_TYPE;
+    _content_field_write($field, 'create');
+  }
+  elseif (!empty($prev_field['widget']) && $prev_field['db_storage'] == CONTENT_DB_STORAGE_PER_CONTENT_TYPE && count($prior_instances) > 0) {
+    // If the database storage has changed, update the field and previous instances.
+    $field['db_storage'] = CONTENT_DB_STORAGE_PER_FIELD;
+
+    foreach ($prior_instances as $instance) {
+      $new_instance = $instance;
+      $new_instance['db_storage'] = CONTENT_DB_STORAGE_PER_FIELD;
+
+      // Invoke hook_content_fieldapi().
+      module_invoke_all('content_fieldapi', 'update instance', $new_instance);
+
+      content_alter_schema($instance, $new_instance);
+    }
+    $prev_field['db_storage'] = CONTENT_DB_STORAGE_PER_FIELD;
+  }
+
+  // Invoke hook_content_fieldapi().
+  module_invoke_all('content_fieldapi', 'create instance', $field);
+
+  // Update the field and the instance with the latest values.
+  _content_field_write($field, 'update');
+  _content_field_instance_write($field, 'create');
+
+  content_alter_schema(empty($prev_field['widget']) ? array() : $prev_field, $field);
+
+  content_clear_type_cache(TRUE);
+  menu_rebuild(TRUE);
+
+  return $field;
 }
 
 /**
- * Update an existing field.
+ * Update an existing field instance.
  *
- * @param $properties
- *   An array of properties to set in the field. Valid keys:
- *   - '' -
- * @return
- *   The number of fields updated.
+ * @param $field
+ *   An array of properties to update the field with, input either in
+ *   the field => widget format used by the content module or as an
+ *   array of form values.
  */
-function content_field_update($properties) {
-  // TODO
+function content_field_instance_update($field) {
+  include_once('./'. drupal_get_path('module', 'content') .'/content_admin.inc');
+
+  // Get the previous value from the table.
+  $previous = content_field_instance_read(array('field_name' => $field['field_name'], 'type_name' => $field['type_name']));
+  $prev_field = array_pop($previous);
+
+  $field = content_field_instance_expand($field);
+
+  // Create a complete field array by merging the previous and current values,
+  // letting the current values overwrite the previous ones.
+  $widget = array_merge($prev_field['widget'], $field['widget']);
+  $field = array_merge($prev_field, $field);
+  $field['widget'] = $widget;
+
+  // Make sure we know what module to invoke for field info.
+  if (empty($field['module']) && !empty($field['type'])) {
+    $field_types = _content_field_types();
+    $field['module'] = $field_types[$field['type']]['module'];
+  }
+
+  // The storage type may need to be updated.
+  $field['db_storage'] = content_storage_type($field);
+
+  // Changes in field values may affect columns, or column
+  // information may have changed, get a fresh copy.
+  $field['columns'] = (array) module_invoke($field['module'], 'field_settings', 'database columns', $field);
+
+  // If the database storage has changed, update the field and previous instances.
+  $prior_instances = content_field_instance_read(array('field_name' => $field['field_name']));
+
+  if ($prev_field['db_storage'] == CONTENT_DB_STORAGE_PER_CONTENT_TYPE && count($prior_instances) > 1) {
+
+    // Update the field's data storage.
+    $field['db_storage'] = CONTENT_DB_STORAGE_PER_FIELD;
+
+    // Update the schema for prior instances to adapt to the change in db storage.
+    foreach ($prior_instances as $instance) {
+      if ($instance['type_name'] != $field['type_name']) {
+        $new_instance = $instance;
+        $new_instance['db_storage'] = CONTENT_DB_STORAGE_PER_FIELD;
+
+        // Invoke hook_content_fieldapi().
+        module_invoke_all('content_fieldapi', 'update instance', $new_instance);
+
+        content_alter_schema($instance, $new_instance);
+      }
+    }
+  }
+
+  // Invoke hook_content_fieldapi().
+  module_invoke_all('content_fieldapi', 'update instance', $field);
+
+  // Update the field and the instance with the latest values.
+  _content_field_write($field, 'update');
+  _content_field_instance_write($field, 'update');
+
+  content_alter_schema($prev_field, $field);
+
+  content_clear_type_cache(TRUE);
+
+  return $field;
 }
 
 /**
- * Delete an existing field.
+ * Write a field record.
  *
- * @param $properties
- *   An array of properties to use in selecting a field. Valid keys:
- *   - 'field_name' - The name of the field to be deleted.
- * @return
- *   The number of fields deleted.
+ * @param $field
+ *   The field array to process.
  */
-function content_field_delete($properties) {
-  $result = db_query("SELECT type_name FROM {node_field_instance} WHERE field_name = '%s'", $properties['field_name']);
-  $type_names = array();
-  while ($type = db_fetch_array($result)) {
-    $type_names[] = $type['type_name'];
+function _content_field_write($field, $op = 'update') {
+  // Rearrange the data to create the global_settings array.
+  $field['global_settings'] = array();
+  // Make sure we know what module to invoke for field info.
+  if (empty($field['module']) && !empty($field['type'])) {
+    $field_types = _content_field_types();
+    $field['module'] = $field_types[$field['type']]['module'];
   }
-  foreach ($type_names as $type_name) {
-    content_field_instance_delete(array('type_name' => $type_name, 'field_name' => $properties['field_name']));
+  $setting_names = module_invoke($field['module'], 'field_settings', 'save', $field);
+  if (is_array($setting_names)) {
+    foreach ($setting_names as $setting) {
+      $field['global_settings'][$setting] = isset($field[$setting]) ? $field[$setting] : '';
+      unset($field[$setting]);
+    }
   }
-  return (count($type_names) ? 1 : 0);
-}
+  // 'columns' is a reserved word in MySQL4, so our column is named 'db_columns'.
+  $field['db_columns'] = $field['columns'];
 
+  switch ($op) {
+    case 'create':
+      db_query("INSERT INTO {node_field} (field_name, type, global_settings, required, multiple, db_storage) VALUES ('%s', '%s', '%s', %d, %d, %d)", $field['field_name'], $field['type'], serialize($field['global_settings']), $field['required'], $field['multiple'], $field['db_storage']);
+      break;
+    case 'update':
+      db_query("UPDATE {node_field} SET type = '%s', global_settings = '%s',
+        required = %d, multiple = %d, db_storage = %d WHERE field_name = '%s'", $field['type'], serialize($field['global_settings']), $field['required'], $field['multiple'], $field['db_storage'], $field['field_name']);
+      break;
+  }
+  unset($field['db_columns']);
+  return $field;
+}
 
 /**
- * Create a new field instance.
+ * Write a field instance record.
  *
- * @param $properties
- *   An array of properties to load the field instance with. Valid keys:
- *   - '' -
- * @return
- *   The ID of the newly-created field instance.
+ * @param $field
+ *   The field array to process.
  */
-function content_field_instance_create($properties) {
-  // TODO
+function _content_field_instance_write($field, $op = 'update') {
+  // Collapse the field => widget format.
+  $field = content_field_instance_collapse($field);
+
+  // Rearrange the data to create the widget_settings array.
+  $setting_names = module_invoke($field['widget_module'], 'widget_settings', 'save', $field);
+  if (is_array($setting_names)) {
+    foreach ($setting_names as $setting) {
+      $field['widget_settings'][$setting] = isset($field[$setting]) ? $field[$setting] : '';
+      unset($field[$setting]);
+    }
+  }
+
+  switch ($op) {
+    case 'create':
+      db_query("INSERT INTO {node_field_instance} (field_name, type_name, weight, label, widget_type, widget_settings, display_settings, description) VALUES ('%s','%s',%d,'%s','%s','%s','%s','%s')", $field['field_name'], $field['type_name'], $field['weight'], $field['label'], $field['widget_type'], serialize($field['widget_settings']), serialize($field['display_settings']), $field['description']);
+      break;
+    case 'update':
+      db_query("UPDATE {node_field_instance} SET weight = %d, label = '%s', widget_type = '%s', widget_settings = '%s', display_settings = '%s', description = '%s' WHERE field_name = '%s' AND type_name = '%s'", $field['weight'], $field['label'], $field['widget_type'], serialize($field['widget_settings']), serialize($field['display_settings']), $field['description'], $field['field_name'], $field['type_name']);
+      break;
+  }
+  return $field;
 }
 
 /**
  * Load a field instance.
  *
- * @param $properties
+ * @param $param
  *   An array of properties to use in selecting a field instance. Valid keys:
  *   - 'type_name' - The name of the content type in which the instance exists.
  *   - 'field_name' - The name of the field whose instance is to be loaded.
+ *   if NULL, all instances will be returned.
  * @return
- *   The field instance array.
+ *   The field arrays.
  */
-function content_field_instance_read($properties) {
-  // TODO
+function content_field_instance_read($param = NULL) {
+  if (is_array($param)) {
+    // Turn the conditions into a query.
+    foreach ($param as $key => $value) {
+      $cond[] = 'nfi.'. db_escape_string($key) ." = '%s'";
+      $args[] = $value;
+    }
+  }
+
+  if (count($cond)) {
+    $cond = implode(' AND ', $cond);
+  }
+  $db_result = db_query("SELECT * FROM {node_field_instance} nfi ".
+    " JOIN {node_field} nf ON nfi.field_name = nf.field_name ".
+    " WHERE ". $cond ." ORDER BY nfi.weight ASC, nfi.label ASC", $args);
+
+  $fields = array();
+  while ($instance = db_fetch_array($db_result)) {
+    // 'columns' is a reserved word in MySQL4, so our column is named 'db_columns'.
+    $instance['columns'] = (array) (!empty($instance['db_columns']) ? unserialize($instance['db_columns']) : array());
+    unset($instance['db_columns']);
+    $instance['global_settings'] = (array) (!empty($instance['global_settings']) ? unserialize($instance['global_settings']) : array());
+
+    foreach ($instance['global_settings'] as $key => $value) {
+      $instance[$key] = $value;
+    }
+    unset($instance['global_settings']);
+
+    if (!empty($instance['widget_settings'])) {
+      $instance['widget_settings'] = (array) unserialize($instance['widget_settings']);
+    }
+    else {
+       $instance['widget_settings'] = array();
+    }
+    if (!empty($instance['display_settings'])) {
+      $instance['display_settings'] = (array) unserialize($instance['display_settings']);
+    }
+    else {
+      $instance['display_settings'] = array();
+    }
+
+    $field = content_field_instance_expand($instance);
+
+    // Invoke hook_content_fieldapi().
+    module_invoke_all('content_fieldapi', 'read instance', $field);
+    $fields[] = $field;
+  }
+  return $fields;
 }
 
 /**
- * Update an existing field instance.
- *
- * @param $properties
- *   An array of properties to set in the field instance. Valid keys:
- *   - '' -
- * @return
- *   The number of field instance updated.
+ * Delete an existing field instance.
  */
-function content_field_instance_update($properties) {
-  // TODO
+function content_field_instance_delete($field_name, $type_name) {
+  include_once('./'. drupal_get_path('module', 'content') .'/content_admin.inc');
+
+  // Get the previous field value.
+  $field = array_pop(content_field_instance_read(array('field_name' => $field_name, 'type_name' => $type_name)));
+
+  // Invoke hook_content_fieldapi().
+  module_invoke_all('content_fieldapi', 'delete instance', $field);
+
+  db_query("DELETE FROM {node_field_instance} WHERE field_name = '%s' AND type_name = '%s'", $field['field_name'], $field['type_name']);
+
+  // If no instances remain, delete the field entirely.
+  $instances = content_field_instance_read(array('field_name' => $field_name));
+  if (sizeof($instances) < 1) {
+    // Remove the fields from the database
+    content_alter_schema($field, array());
+
+    db_query("DELETE FROM {node_field} WHERE field_name = '%s'", $field['field_name']);
+
+    // Deleted fields require a menu rebuild to remove all the field paths.
+    menu_rebuild(TRUE);
+  }
+
+  // If only one instance remains, we may need to change the database
+  // representation for this field.
+  if (sizeof($instances) == 1 && !($field['multiple'])) {
+
+    // Multiple-valued fields are always stored per-field-type.
+    $instance = $instances[0];
+    $new_instance = $instance;
+    $new_instance['db_storage'] = CONTENT_DB_STORAGE_PER_CONTENT_TYPE;
+    _content_field_write($new_instance, 'update');
+
+    content_alter_schema($instance, $new_instance);
+  }
+
+  content_clear_type_cache(TRUE);
+  return $field;
 }
 
 /**
- * Delete an existing field instance.
+ * Delete all data related to a module.
  *
- * @param $properties
- *   An array of properties to use in selecting a field instance. Valid keys:
- *   - 'type_name' - The name of the content type in which the instance exists.
- *   - 'field_name' - The name of the field whose instance is to be deleted.
- * @return
- *   The number of field instances deleted.
+ * @param string $module
  */
-function content_field_instance_delete($properties) {
-  $number_deleted = db_query("DELETE FROM {node_field_instance} WHERE type_name = '%s' AND field_name = '%s'", $properties['type_name'], $properties['field_name']);
+function content_module_delete($module) {
+  // Delete the field data.
+  $results = db_query("SELECT field_name, type_name FROM {node_field_instance} WHERE widget_module = '%s'", $module);
+  while ($field = db_fetch_array($results)) {
+    content_field_instance_delete($field['field_name'], $field['type_name']);
+  }
+  // Force the caches and static arrays to update to the new info.
+  _content_type_info(TRUE, TRUE);
 
-  $type = content_types($properties['type_name']);
-  $field = $type['fields'][$properties['field_name']];
-  $field_types = _content_field_types();
-  $field_type = $field_types[$field['type']];
-  $columns = module_invoke($field_type['module'], 'field_settings', 'database columns', $field);
+}
 
-  $instances = db_result(db_query("SELECT COUNT(*) FROM {node_field_instance} WHERE field_name = '%s'", $properties['field_name']));
+/**
+ * Make changes needed when a content type is created.
+ *
+ * @param $info
+ *   value supplied by hook_node_type()
+ *
+ * node_get_types() is still missing the new type at this point, so no
+ * use to call content_clear_type_cache() or menu_rebuild() here. Instead
+ * we set a flag to make sure it gets rebuilt on next page load.
+ */
+function content_type_create($info) {
+  content_clear_type_cache();
+  $type = content_types($info->type);
+  $table = _content_tablename($type['type'], CONTENT_DB_STORAGE_PER_CONTENT_TYPE);
+  if (!db_table_exists($table)) {
+    switch ($GLOBALS['db_type']) {
+      case 'mysql':
+      case 'mysqli':
+        db_query("CREATE TABLE {". $table ."} (
+          vid int unsigned NOT NULL default '0',
+          nid int unsigned NOT NULL default '0',
+          PRIMARY KEY (vid)
+        ) /*!40100 DEFAULT CHARACTER SET utf8 */");
+      break;
 
-  // If only one instance remains, we may need to change the database
-  // representation for this field.
-  if ($instances == 1) {
-    if (!($field['multiple'])) {
-      // Multiple-valued fields are always stored per-content-type.
-      if (is_array($columns) && count($columns)) {
-        $new_field = $field;
-        $new_field['db_storage'] = CONTENT_DB_STORAGE_PER_CONTENT_TYPE;
-        db_query("UPDATE {node_field} SET db_storage = %d WHERE field_name = '%s'", CONTENT_DB_STORAGE_PER_CONTENT_TYPE, $properties['field_name']);
-        content_alter_db_field($field, $columns, $new_field, $columns);
-      }
+      case 'pgsql':
+        db_query("CREATE TABLE {". $table ."} (
+          vid int_unsigned NOT NULL default '0',
+          nid int_unsigned NOT NULL default '0',
+          PRIMARY KEY (vid)
+        )");
+      break;
     }
+    drupal_set_message(t('The content fields table %name has been created.', array('%name' => $table)));
   }
+}
 
-  // If no instances remain, delete the field entirely.
-  elseif ($instances == 0) {
-    if (is_array($columns) && count($columns)) {
-      content_alter_db_field($field, $columns, array(), array());
+/**
+ * Make changes needed when an existing content type is updated.
+ *
+ * @param $info
+ *   value supplied by hook_node_type()
+ */
+function content_type_update($info) {
+  if (!empty($info->old_type) && $info->old_type != $info->type) {
+    // Rename the content type in all fields that use changed content type.
+    db_query("UPDATE {node_field_instance} SET type_name='%s' WHERE type_name='%s'", array($info->type, $info->old_type));
+
+    // Rename the content fields table to match new content type name.
+    $old_type = content_types($info->old_type);
+    $old_name = _content_tablename($old_type['type'], CONTENT_DB_STORAGE_PER_CONTENT_TYPE);
+    $new_name = _content_tablename($info->type, CONTENT_DB_STORAGE_PER_CONTENT_TYPE);
+    if (db_table_exists($old_name)) {
+      $ret = array();
+      db_rename_table($ret, $old_name, $new_name);
+      watchdog('content', 'Content fields table %old_name has been renamed to %new_name and field instances have been updated.', array(
+        '%old_name' => $old_name, '%new_name' => $new_name));
+    }
+
+    // Rename the variable storing weights for non-CCK fields.
+    if ($extra = variable_get('content_extra_weights_'. $info->old_type, array())) {
+      variable_set('content_extra_weights_'. $info->type, $extra);
+      variable_del('content_extra_weights_'. $info->old_type);
     }
-    db_query("DELETE FROM {node_field} WHERE field_name = '%s'", $properties['field_name']);
   }
 
+  // Reset all content type info and alter the menu paths.
   content_clear_type_cache();
+  menu_rebuild();
+}
+
+/**
+ * Make changes needed when a content type is deleted.
+ *
+ * @param $info
+ *   value supplied by hook_node_type()
+ */
+function content_type_delete($info) {
+  $fields = content_field_instance_read(array('type_name' => $info->type));
+  foreach ($fields as $field) {
+    content_field_instance_delete($field['field_name'], $info->type);
+  }
+  $table = _content_tablename($info->type, CONTENT_DB_STORAGE_PER_CONTENT_TYPE);
+  if (db_table_exists($table)) {
+    $ret = array();
+    db_query('DROP TABLE {'. $table .'}');
+    watchdog('content', 'The content fields table %name has been deleted.', array('%name' => $table));
+  }
 
-  return $number_deleted;
+  menu_rebuild(TRUE);
 }
diff --git a/po/vi.po b/po/vi.po
index a1b0dd7..eab603f 100644
--- a/po/vi.po
+++ b/po/vi.po
@@ -20,8 +20,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: CCK 5.x-1.7.x\n"
 "POT-Creation-Date: 2008-03-24 03:11+0100\n"
-"PO-Revision-Date: 2008-05-03 09:02+0700\n"
-"Last-Translator: The Hong Truong <thehongtt@gmail.com>\n"
+"PO-Revision-Date: 2008-05-07 06:20+0700\n"
+"Last-Translator: The Hong <thehong@toila.net>\n"
 "Language-Team: Vietnamese Translation Team <thehong@toila.net>\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
@@ -49,7 +49,7 @@ msgstr "Độ dài tối đa"
 #: field.php:112
 #: text.module:37
 msgid "The maximum length of the field in characters. Leave blank for an unlimited size."
-msgstr "Số lượng ký tự tối đa của trường. Bỏ trống nếu muốn không giới hạn."
+msgstr "Số lượng ký tự tối đa của trường dữ liệu. Bỏ trống nếu muốn không giới hạn."
 
 #: field.php:220
 #: number.module:144
@@ -92,11 +92,11 @@ msgstr "\"Số dòng\" phải là số dương."
 
 #: content_admin.inc:15
 msgid "Field name"
-msgstr "Tên trường"
+msgstr "Tên trường dữ liệu"
 
 #: content_admin.inc:15;529
 msgid "Field type"
-msgstr "Kiểu trường"
+msgstr "Kiểu trường dữ liệu"
 
 #: content_admin.inc:15
 msgid "Used in"
@@ -108,7 +108,7 @@ msgstr "Không có nhóm nào được cấu hình cho kiểu nội dung này."
 
 #: content_admin.inc:83;363
 msgid "There are no fields configured for this content type."
-msgstr "Không có trường nào được cấu hình cho kiểu nội dung này."
+msgstr "Không có trường dữ liệu nào được cấu hình cho kiểu nội dung này."
 
 #: content_admin.inc:108
 msgid "group"
@@ -158,7 +158,7 @@ msgstr "Các thao tác"
 
 #: content_admin.inc:280
 msgid "No fields have been added to this group."
-msgstr "Chưa có trường nào được thêm vào nhóm này."
+msgstr "Chưa có trường dữ liệu nào được thêm vào nhóm này."
 
 #: content_admin.inc:285
 msgid "!label (!name)"
@@ -166,7 +166,7 @@ msgstr "!label (!name)"
 
 #: content_admin.inc:320
 msgid "Updated field groups."
-msgstr "Đã cập nhật nhóm các trường."
+msgstr "Đã cập nhật nhóm các trường dữ liệu."
 
 #: content_admin.inc:331
 msgid "Updated group weights."
@@ -174,7 +174,7 @@ msgstr "Đã cập nhật độ nặng của các nhóm."
 
 #: content_admin.inc:342
 msgid "Updated field weights."
-msgstr "Đã cập nhật độ nặng của các trường."
+msgstr "Đã cập nhật độ nặng của các trường dữ liệu."
 
 #: content_admin.inc:371
 #: content_copy.module:164;237
@@ -184,7 +184,7 @@ msgstr "Đệ trình"
 
 #: content_admin.inc:376
 msgid "Field"
-msgstr "Trường"
+msgstr "Trường dữ liệu"
 
 #: content_admin.inc:411
 msgid "Your settings have been saved."
@@ -215,7 +215,7 @@ msgstr "Bản đầy đủ"
 
 #: content_admin.inc:483
 msgid "Add existing field"
-msgstr "Thêm trường đã có"
+msgstr "Thêm trường dữ liệu đã có"
 
 #: content_admin.inc:492
 #: content.module:125
@@ -224,43 +224,43 @@ msgstr "Thêm trường"
 
 #: content_admin.inc:518
 msgid "Create new field"
-msgstr "Tạo trường mới"
+msgstr "Tạo trường dữ liệu mới"
 
 #: content_admin.inc:524
 msgid "The machine-readable name of the field.<br/>Allowed characters : unaccentuated a-z, numbers and _. All other characters will be discarded.<br/>You'll be able to choose a human-readable label for the field on next page"
-msgstr "Tên của trường dành cho máy đọc.<br />Các ký tự cho phép: a-z (không viết in), 0-9 và dấu _. Các ký tự khác đều bị loại bỏ.<br />Bạn sẽ có thể chọn nhãn dễ đọc cho trường ở trang kế"
+msgstr "Tên của trường dữ liệu dành cho máy đọc.<br />Các ký tự cho phép: a-z (không viết in), 0-9 và dấu _. Các ký tự khác đều bị loại bỏ.<br />Bạn sẽ có thể chọn nhãn dễ đọc cho trường ở trang kế"
 
 #: content_admin.inc:537
 msgid "Create field"
-msgstr "Tạo trường"
+msgstr "Tạo trường dữ liệu"
 
 #: content_admin.inc:549
 msgid "No field modules are enabled. You need to <a href=\"!modules_url\">enable one</a>, such as text.module, before you can add new fields."
-msgstr "Không có module trường nào được kích hoạt. Bạn cần <a href=\"!modules_url\">kích hoạt</a> ít nhất là một, như text.module, trước khi bạn tạo ra các trường mới."
+msgstr "Không có module trường dữ liệu nào được kích hoạt. Bạn cần <a href=\"!modules_url\">kích hoạt</a> ít nhất là một, như text.module, trước khi bạn tạo ra các trường mới."
 
 #: content_admin.inc:605
 msgid "Added field %label."
-msgstr "Đã thêm trường %label."
+msgstr "Đã thêm trường dữ liệu %label."
 
 #: content_admin.inc:617
 msgid "The field name %field_name already exists."
-msgstr "Tên trường %field_name đã tồn tại."
+msgstr "Tên trường dữ liệu %field_name đã tồn tại."
 
 #: content_admin.inc:621
 msgid "The field name %field_name is invalid."
-msgstr "Tên trường %field_name không hợp lệ."
+msgstr "Tên trường dữ liệu %field_name không hợp lệ."
 
 #: content_admin.inc:672
 msgid "Created field %label."
-msgstr "Đã tạo trường %label."
+msgstr "Đã tạo trường dữ liệu %label."
 
 #: content_admin.inc:694
 msgid "Are you sure you want to remove the field %field?"
-msgstr "Bạn có chắc là muốn xóa trường %field?"
+msgstr "Bạn có chắc là muốn xóa trường dữ liệu %field?"
 
 #: content_admin.inc:696
 msgid "If you have any content left in this field, it will be lost. This action cannot be undone."
-msgstr "Nếu bạn có nội dung nào ở trong trường này, nó sẽ bị mất. Thao tác này không thể hoàn hồi."
+msgstr "Nếu bạn có nội dung nào ở trong trường dữ liệu này, nó sẽ bị mất. Thao tác này không thể hoàn hồi."
 
 #: content_admin.inc:697
 #: fieldgroup.module:215
@@ -274,7 +274,7 @@ msgstr "Hủy bỏ"
 
 #: content_admin.inc:715
 msgid "Removed field %field from %type."
-msgstr "Đã bỏ đi trường %field khỏi %type."
+msgstr "Đã bỏ đi trường dữ liệu %field khỏi %type."
 
 #: content_admin.inc:738
 msgid "Widget settings"
@@ -282,7 +282,7 @@ msgstr "Các thiết lập widget"
 
 #: content_admin.inc:739
 msgid "These settings apply only to the %field field as it appears in the %type content type."
-msgstr "Các thiết lập này chỉ áp dụng cho trường $field khi nó hiển thị trong kiểu nội dung %type."
+msgstr "Các thiết lập này chỉ áp dụng cho trường dữ liệu $field khi nó hiển thị trong kiểu nội dung %type."
 
 #: content_admin.inc:753
 msgid "Widget"
@@ -295,7 +295,7 @@ msgstr "Bản văn trợ giúp"
 
 #: content_admin.inc:777
 msgid "Instructions to present to the user below this field on the editing form."
-msgstr "Phần hướng dẫn, được trình bày cho người dùng, ở phía dưới trường này trong biểu mẫu soạn thảo."
+msgstr "Phần hướng dẫn, được trình bày cho người dùng, ở phía dưới trường dữ liệu này trong biểu mẫu soạn thảo."
 
 #: content_admin.inc:786
 msgid "Default value"
@@ -324,7 +324,7 @@ msgstr "Các thiết lập dữ liệu"
 
 #: content_admin.inc:838
 msgid "These settings apply to the %field field in every content type in which it appears."
-msgstr "Các thiết lập áp dụng cho trường %field trong mỗi kiểu nội dung mà nó xuất hiện."
+msgstr "Các thiết lập áp dụng cho trường dữ liệu %field trong mỗi kiểu nội dung mà nó xuất hiện."
 
 #: content_admin.inc:842
 msgid "Required"
@@ -352,7 +352,7 @@ msgstr "Giá trị mặc định không hợp lệ."
 
 #: content_admin.inc:1022
 msgid "Saved field %field."
-msgstr "Đã lưu trường %field."
+msgstr "Đã lưu trường dữ liệu %field."
 
 #: content_admin.inc:1329;1426
 msgid "No PostgreSQL mapping found for %type data type."
@@ -436,11 +436,11 @@ msgstr "Trường dữ liệu tham chiếu người dùng"
 
 #: content_views.inc:71
 msgid "Group multiple values"
-msgstr "Nhóm lại các trường đa giá trị"
+msgstr "Nhóm lại các trường dữ liệu nhiều giá trị"
 
 #: content_views.inc:72
 msgid "Do not group multiple values"
-msgstr "Không nhóm lại các trường đa giá trị"
+msgstr "Không nhóm lại các trường dữ liệu nhiều giá trị"
 
 #: content_views.inc:73
 msgid "Show first value only"
@@ -460,11 +460,11 @@ msgstr ""
 
 #: content.module:21
 msgid "Custom field types are provided by a set of optional modules included with CCK (each module provides a different type). The <a href=\"@modules\">modules page</a> allows you to enable or disable CCK components. A default installation of CCK includes:"
-msgstr ""
+msgstr "Các kiểu trường nội dung tùy chỉnh được cung cấp bởi các module tùy chọn được bao gồm với CCK (mỗi module cung cấp các kiểu trường dữ liệu khác nhau). <a href=\"@modules\">Trang module</a> cho phép bạn kích hoạt hoặc ngưng kích hoạt các gói chức năng. Bản cài đặt mặc định của CCK bao gồm:"
 
 #: content.module:23
 msgid "<em>number</em>, which adds numeric field types, in integer, decimal or floating point form. You may define a set of allowed inputs, or specify an allowable range of values. A variety of common formats for displaying numeric data are available."
-msgstr ""
+msgstr "<em>số</em>, cung cấp chức năng thêm các kiểu trường dữ liệu số (số nguyên, só thập phân hoặc số thực) vào kiểu nội dung. Bạn có thể định nghĩa một tập hợp các giá trí được chấp nhận để nhập vào hoặc xác định một khoảng các giá trị được phép. Đã có sẵn các định dạng trình bày thông thường cho dữ liệu số."
 
 #: content.module:24
 msgid "<em>text</em>, which adds text field types. A text field may contain plain text only, or optionally, may use Drupal's input format filters to securely manage rich text input. Text input fields may be either a single line (text field), multiple lines (text area), or for greater input control, a select box, checkbox, or radio buttons. If desired, CCK can validate the input to a set of allowed values."
@@ -488,12 +488,12 @@ msgstr "Để có thêm thông tin, xem sổ tay trực tuyến trang <a href=\"
 
 #: content.module:34
 msgid "Configure how this content type's fields and field labels should be displayed when it's viewed in teaser and full-page mode."
-msgstr "Cấu hình cách trình bày giá trị của trường và nhãn của trường ở bản cắt và ở trang đầy đủ."
+msgstr "Cấu hình cách trình bày giá trị của trường dữ liệu và nhãn của trường ở bản cắt và ở trang đầy đủ."
 
 #: content.module:86
 #: content_copy.module:135
 msgid "Fields"
-msgstr "Các trường"
+msgstr "Các trường dữ liệu"
 
 #: content.module:100
 msgid "Edit"
@@ -501,15 +501,15 @@ msgstr "Sửa"
 
 #: content.module:107
 msgid "Manage fields"
-msgstr "Quản lý trường"
+msgstr "Quản lý các trường dữ liệu"
 
 #: content.module:116
 msgid "Display fields"
-msgstr "Trình bày trường"
+msgstr "Trình bày các trường dữ liệu"
 
 #: content.module:144
 msgid "Remove field"
-msgstr "Bỏ trường"
+msgstr "Bỏ trường dữ liệu"
 
 #: content.module:0
 msgid "content"
@@ -525,7 +525,7 @@ msgstr "Nhập vào"
 
 #: content_copy.module:87
 msgid "This form will process a content type and one or more fields from that type and export the settings. The export created by this process can be copied and pasted as an import into the current or any other database. The import will add the fields to into an existing content type or create a new content type that includes the selected fields."
-msgstr "Biểu mẫu này sẽ xử lý một kiểu nội dung vào một/nhiều trường từ kiểu nội dung đó và xuất ra các thiết lập. Bản xuất ra được tạo bởi quá trình xử lý này có thể được sao chép và dán vào cơ sở dữ liệu hiện tại hoặc cơ sở dữ liệu khác, sử dụng chức năng nhập vào. Chức năng nhập vào sẽ thêm các trường vào kiểu nội dung hiện có hoặc tạo một kiểu nội dung mới bao gồm các trường đã được chọn."
+msgstr "Biểu mẫu này sẽ xử lý một kiểu nội dung vào một/nhiều trường dữ liệu từ kiểu nội dung đó và xuất ra các thiết lập. Bản xuất ra được tạo bởi quá trình xử lý này có thể được sao chép và dán vào cơ sở dữ liệu hiện tại hoặc cơ sở dữ liệu khác, sử dụng chức năng nhập vào. Chức năng nhập vào sẽ thêm các trường vào kiểu nội dung hiện có hoặc tạo một kiểu nội dung mới bao gồm các trường đã được chọn."
 
 #: content_copy.module:96
 msgid "Types"
@@ -601,23 +601,23 @@ msgstr "Thoát. Không thực hiện nhập dữ liệu."
 
 #: content_copy.module:338
 msgid "An error has occured adding the content type %type.<br/>Please check the errors displayed for more details."
-msgstr "Có lỗi xảy ra khi thêm vào kiểu dữ liệu %type.<br />Vui lòng kiểm tra các lỗi được trình bày để có thêm chi tiết."
+msgstr "Có lỗi xảy ra khi thêm kiểu dữ liệu %type.<br />Vui lòng kiểm tra các lỗi được trình bày để có thêm chi tiết."
 
 #: content_copy.module:374
 msgid "The imported field %field_label (%field_name) was not added to %type because that field already exists in %type."
-msgstr "Trường %field_label (%field_name) nhập vào không được thêm vào %type bởi vì trường đó đã tồn tại trong %type."
+msgstr "Trường dữ liệu %field_label (%field_name) nhập vào không được thêm vào %type bởi vì nó đã tồn tại trong %type."
 
 #: content_copy.module:395;414
 msgid "An error has occured adding the field %field_label (%field_name).<br/>Please check the errors displayed for more details."
-msgstr "Có lỗi xảy ra khi thêm vào trường %field_label (%field_name).<br />Vui lòng kiểm tra các lỗi được trình bày để có thêm chi tiết."
+msgstr "Có lỗi xảy ra khi thêm vào trường dữ liệu %field_label (%field_name).<br />Vui lòng kiểm tra các lỗi được trình bày để có thêm chi tiết."
 
 #: content_copy.module:428
 msgid "The field %field_label (%field_name) was added to the content type %type, but an error has occured updating the field settings.<br/>Please check the errors displayed for more details."
-msgstr "Trường $field_label (%field_name) đã được thêm vào kiểu nội dung %type, nhưng một lỗi đã xảy ra khi cập nhật các thiết lập của trường.<br />Vui lòng kiểm tra các lỗi được trình bày để cho thêm chi tiết."
+msgstr "Trường dữ liệu $field_label (%field_name) đã được thêm vào kiểu nội dung %type, nhưng một lỗi đã xảy ra khi cập nhật các thiết lập của trường.<br />Vui lòng kiểm tra các lỗi được trình bày để cho thêm chi tiết."
 
 #: content_copy.module:441
 msgid "The field %field_label (%field_name) was added to the content type %type, but an error has occured updating the field's 'display_settings'.<br/>The db error is: '%db_err'."
-msgstr "Trường dữ liệu $field_label (%field_name) đã được thêm vào kiểu nội dung %type, nhưng một lỗi đã xảy ra khi cập nhật 'display_settings' của trường.<br />Lỗi CSDL: '%db_err'."
+msgstr "Trường dữ liệu $field_label (%field_name) đã được thêm vào kiểu nội dung %type, nhưng một lỗi đã xảy ra khi cập nhật 'display_settings' của trường dữ liệu.<br />Lỗi CSDL: '%db_err'."
 
 #: content_copy.module:578
 msgid "An error occurred when exporting the 'display settings' data for the field %field_name.<br/>The db error is: '%db_err'."
@@ -665,7 +665,7 @@ msgstr "thâu gọn"
 
 #: fieldgroup.module:108
 msgid "Instructions to present to the user on the editing form."
-msgstr "PHần hướng dẫn trình bày cho người dùng trên biểu mẫu soạn thảo."
+msgstr "Phần hướng dẫn trình bày cho người dùng trên biểu mẫu soạn thảo."
 
 #: fieldgroup.module:114
 msgid "These settings apply to the group on node display."
@@ -697,7 +697,7 @@ msgstr "Thao tác này không thể hoàn hồi."
 
 #: fieldgroup.module:223
 msgid "The group %group_name has been removed."
-msgstr "Nhoms %group_name đã được gỡ bỏ."
+msgstr "Nhóm %group_name đã được gỡ bỏ."
 
 #: fieldgroup.module:276
 msgid "No group"
@@ -737,16 +737,16 @@ msgstr "fieldgroup"
 
 #: nodereference.module:17
 msgid "node reference autocomplete"
-msgstr "tự động tham khảo node"
+msgstr "tham khảo node tự động"
 
 #: nodereference.module:29
 #: nodereference.info:0
 msgid "Node Reference"
-msgstr "Tham khảo Node"
+msgstr "Tham chiếu Node"
 
 #: nodereference.module:42
 msgid "Content types that can be referenced"
-msgstr "Các kiểu nội dung có thể được tham khảo"
+msgstr "Các kiểu nội dung có thể được tham chiếu"
 
 #: nodereference.module:51
 msgid "Existing Views"
@@ -758,7 +758,7 @@ msgstr "Views mặc định"
 
 #: nodereference.module:61
 msgid "Advanced - Nodes that can be referenced (View)"
-msgstr "Nâng cao - Các node có thể được tham khảo (View)"
+msgstr "Nâng cao - Các node có thể được tham chiếu (View)"
 
 #: nodereference.module:67
 msgid "View"
@@ -766,7 +766,7 @@ msgstr "Xem"
 
 #: nodereference.module:70
 msgid "Choose the \"Views module\" view that selects the nodes that can be referenced.<br>Note :<ul><li>This will discard the \"Content types\" settings above. Use the view's \"filters\" section instead.</li><li>Use the view's \"fields\" section to display additional informations about candidate nodes on node creation/edition form.</li><li>Use the view's \"sort criteria\" section to determine the order in which candidate nodes will be displayed.</li></ul>"
-msgstr "Chọn view ( được tạo ra bởi module \"Views module\"), chỉ những node được chọn ra bởi view này mới có thể được tham khảo.<br>Ghi chú:<ul><li>Thiết lập này sẽ bỏ qua các thiết lập \"Các kiểu nội dung\" ở trên. Use the view's \"filters\" section instead.</li><li>Sử dụng view's \"fields\" section để trình bày thêm thông tin về candidate nodes trên biểu mẫu soạn thảo node.</li><li>Sử dụng the view's \"sort criteria\" section to determine the order in which candidate nodes will be displayed.</li></ul>"
+msgstr "Chọn view ( được tạo ra bởi module \"Views module\"), chỉ những node được chọn ra bởi view này mới có thể được tham chiếu.<br>Ghi chú:<ul><li>Thiết lập này sẽ bỏ qua các thiết lập \"Các kiểu nội dung\" ở trên. Use the view's \"filters\" section instead.</li><li>Sử dụng view's \"fields\" section để trình bày thêm thông tin về candidate nodes trên biểu mẫu soạn thảo node.</li><li>Sử dụng the view's \"sort criteria\" section to determine the order in which candidate nodes will be displayed.</li></ul>"
 
 #: nodereference.module:74
 msgid "View arguments"
@@ -778,7 +778,7 @@ msgstr "Dấu phẩy phân cách các tham số truyền vào view."
 
 #: nodereference.module:122
 msgid "%name : This post can't be referenced."
-msgstr "%name: Bài viết này không thể được tham khảo."
+msgstr "%name: Bài viết này không thể được tham chiếu."
 
 #: nodereference.module:136
 msgid "Title (link)"
@@ -817,7 +817,7 @@ msgstr "<rỗng>"
 
 #: nodereference.module:0
 msgid "nodereference"
-msgstr "tham khảo node"
+msgstr "tham chiếu node"
 
 #: number.module:33
 msgid "Minimum"
@@ -851,7 +851,7 @@ msgstr "Danh sách các giá trị được phép"
 #: number.module:61
 #: text.module:45
 msgid "The possible values this field can contain. Enter one value per line, in the format key|label. The key is the value that will be stored in the database and it must match the field storage type, %type. The label is optional and the key will be used as the label if no label is specified."
-msgstr "Các giá trị mà trường này có thể chứa. Nhập một giá trị vào mỗi dòng, với định dạng khóa|nhãn. Khóa là giá trị được lưu trữ ở cơ sở dữ liệu, nó phải trùng khớp với kiểu lưu trữ của trường. Nhãn là một tùy chọn và khóa sẽ được sử dụng như nhãn nếu nhãn không được thiết lập."
+msgstr "Các giá trị mà trường dữ liệu này có thể chứa. Nhập một giá trị vào mỗi dòng, với định dạng khóa|nhãn. Khóa là giá trị được lưu trữ ở cơ sở dữ liệu, nó phải trùng khớp với kiểu lưu trữ của trường dữ liệu. Nhãn là một tùy chọn và khóa sẽ được sử dụng như một nhãn nếu nhãn không được thiết lập."
 
 #: number.module:74
 #: text.module:58
@@ -898,7 +898,7 @@ msgstr ""
 
 #: optionwidgets.module:34
 msgid "Select list"
-msgstr "Danh ách lự chọna"
+msgstr "Danh sách lựa chọn"
 
 #: optionwidgets.module:38
 msgid "Check boxes/radio buttons"
@@ -927,7 +927,7 @@ msgstr "Bản văn được lọc (người dùng chọn định dạng dữ li
 
 #: text.module:28
 msgid "Text processing"
-msgstr "Xử lý"
+msgstr "Xử lý bản văn"
 
 #: text.module:87
 msgid "Set the option to the number of initial characters to filter by. Leave empty for full term; use 1 for an A/B/C style glossary."
@@ -948,15 +948,15 @@ msgstr "tự động tham chiếu người dùng"
 #: userreference.module:28
 #: userreference.info:0
 msgid "User Reference"
-msgstr "Tham khảo người dùng"
+msgstr "Tham chiếu người dùng"
 
 #: userreference.module:41
 msgid "User roles that can be referenced"
-msgstr "Các vai trò người dùng có thể được tham khảo tới"
+msgstr "Các vai trò người dùng có thể được tham chiếu tới"
 
 #: userreference.module:47
 msgid "User status that can be referenced"
-msgstr "Tình trạng người dùng có thể được tham khảo tới"
+msgstr "Tình trạng người dùng có thể được tham chiếu tới"
 
 #: userreference.module:49
 msgid "Active"
@@ -992,11 +992,11 @@ msgstr "Nội dung liên quan"
 
 #: userreference.module:0
 msgid "userreference"
-msgstr "tham khảo người dùng"
+msgstr "tham chiếu người dùng"
 
 #: optionwidgets.install:77
 msgid "<div>The allowed values list for %field was updated from </div><pre>%start</pre><div> to </div><pre>%end</pre><div>You can go to the field settings page to give each option a more user-friendly label."
-msgstr "<div>Danh sách các giá trị được phép cho %field đã được cập nhật từ <div> <pre>%start</pre><div>đến</div><pre>%end</pre><div>Bạn có thể đến trang cấu hình trường để gắn nhãn, thân thiện hơn với người dùng."
+msgstr "<div>Danh sách các giá trị được phép cho %field đã được cập nhật từ <div> <pre>%start</pre><div>đến</div><pre>%end</pre><div>Bạn có thể đến trang cấu hình trường dữ liệu để gắn nhãn, thân thiện hơn với người dùng."
 
 #: optionwidgets.install:80
 msgid "<div>The allowed values list for %field was not changed from </div><pre>%start</pre>"
@@ -1027,7 +1027,7 @@ msgstr "Sao chép nội dung"
 
 #: content_copy.info:0
 msgid "Enables ability to import/export field definitions."
-msgstr "Kích hoạt khả năng nhập/xuất các định nghĩa trường."
+msgstr "Kích hoạt khả năng nhập/xuất các định nghĩa trường dữ liệu."
 
 #: fieldgroup.info:0
 msgid "Fieldgroup"
@@ -1035,7 +1035,7 @@ msgstr "Fieldgroup"
 
 #: fieldgroup.info:0
 msgid "Create field groups for CCK fields."
-msgstr "Tạo các nhóm trường cho các trường CCK."
+msgstr "Tạo các nhóm cho các trường dữ liệu CCK."
 
 #: nodereference.info:0
 msgid "Defines a field type for referencing one node from another."
@@ -1047,7 +1047,7 @@ msgstr "Số"
 
 #: number.info:0
 msgid "Defines numeric field types."
-msgstr "Định nghĩa các trường số"
+msgstr "Định nghĩa các trường dữ liệu số"
 
 #: optionwidgets.info:0
 msgid "Option Widgets"
@@ -1055,15 +1055,15 @@ msgstr "Các widget tùy chọn"
 
 #: optionwidgets.info:0
 msgid "Defines selection, check box and radio button widgets for text and numeric fields."
-msgstr "Định nghĩa chọn lựa, hộp kiểm tra và các nút radio cho bản văn và các trường số."
+msgstr "Định nghĩa chọn lựa, hộp kiểm tra và các nút radio cho bản văn và các trường dữ liệu số."
 
 #: text.info:0
 msgid "Defines simple text field types."
-msgstr "Định nghĩa các kiểu trường bản văn đơn giản."
+msgstr "Định nghĩa các kiểu trường dữ liệu bản văn đơn giản."
 
 #: userreference.info:0
 msgid "Defines a field type for referencing a user from a node."
-msgstr "Định nghĩa một kiểu trường để tham khảo đến một người dùng từ một node."
+msgstr "Định nghĩa một kiểu trường dữ liệu để tham khảo đến một người dùng từ một node."
 
 #: theme/node-content_example.tpl.php:6
 msgid "!date — !username"
