From a9cc9fc48e0cd1a587dd75f718fbe2cb43ec7086 Mon Sep 17 00:00:00 2001
From: Jonathan Chaffer <jonbob@831.no-reply.drupal.org>
Date: Thu, 3 Nov 2005 15:46:17 +0000
Subject: [PATCH] Split field.module up into separate field-type modules.

---
 README.txt     |   8 +-
 cck.mysql      |  29 +-
 content.module |  25 +-
 date.module    | 235 +++++++++++++++++
 field.module   | 701 -------------------------------------------------
 list.module    |  30 +--
 number.module  | 296 +++++++++++++++++++++
 text.module    | 307 ++++++++++++++++++++++
 8 files changed, 886 insertions(+), 745 deletions(-)
 create mode 100644 date.module
 delete mode 100644 field.module
 create mode 100644 number.module
 create mode 100644 text.module

diff --git a/README.txt b/README.txt
index 151dbeb5..68dfa827 100644
--- a/README.txt
+++ b/README.txt
@@ -6,10 +6,14 @@ This is still in development. Do not use on production sites.
 
 To test, add cck.mysql to your database. Place the cck folder
 into your modules directory. Go to administer -> modules and enable
-the content and field modules (optionally, list.module).
+the content module and one or more field type modules:
+- text.module
+- number.module
+- date.module
 
 Now go to administer -> content -> content types. Create a new
 content type and edit it to add some fields. Then test by
 creating a new node of your new type.
 
-jvandyk [at] iastate.edu
\ No newline at end of file
+jvandyk [at] iastate.edu
+jchaffer [at] structureinteractive.com
\ No newline at end of file
diff --git a/cck.mysql b/cck.mysql
index 3a46e3e8..058fc08a 100644
--- a/cck.mysql
+++ b/cck.mysql
@@ -1,3 +1,4 @@
+# content.module
 
 CREATE TABLE node_type (
   type_name varchar(31) NOT NULL default '',
@@ -27,42 +28,48 @@ CREATE TABLE node_field_instance (
 ) TYPE=MyISAM;
 
 
-# field data
+# text.module
 
-CREATE TABLE `node_field_float_data` (
+CREATE TABLE `node_field_longtext_data` (
   `vid` int unsigned NOT NULL default '0',
   `field_name` varchar(31) NOT NULL default '',
   `delta` int unsigned NOT NULL default '0',
-  `field_float` float NOT NULL default '0',
+  `field_longtext` mediumtext NOT NULL,
+  `format` int NOT NULL default '0',
   PRIMARY KEY  (`vid`,`field_name`,`delta`)
 ) TYPE=MyISAM;
 
-CREATE TABLE `node_field_int_data` (
+CREATE TABLE `node_field_shorttext_data` (
   `vid` int unsigned NOT NULL default '0',
   `field_name` varchar(31) NOT NULL default '',
   `delta` int unsigned NOT NULL default '0',
-  `field_int` int NOT NULL default '0',
+  `field_shorttext` varchar(255) NOT NULL default '',
+  `format` int NOT NULL default '0',
   PRIMARY KEY  (`vid`,`field_name`,`delta`)
 ) TYPE=MyISAM;
 
-CREATE TABLE `node_field_longtext_data` (
+
+# number.module
+
+CREATE TABLE `node_field_float_data` (
   `vid` int unsigned NOT NULL default '0',
   `field_name` varchar(31) NOT NULL default '',
   `delta` int unsigned NOT NULL default '0',
-  `field_longtext` mediumtext NOT NULL,
-  `format` int NOT NULL default '0',
+  `field_float` float NOT NULL default '0',
   PRIMARY KEY  (`vid`,`field_name`,`delta`)
 ) TYPE=MyISAM;
 
-CREATE TABLE `node_field_shorttext_data` (
+CREATE TABLE `node_field_int_data` (
   `vid` int unsigned NOT NULL default '0',
   `field_name` varchar(31) NOT NULL default '',
   `delta` int unsigned NOT NULL default '0',
-  `field_shorttext` varchar(255) NOT NULL default '',
-  `format` int NOT NULL default '0',
+  `field_int` int NOT NULL default '0',
   PRIMARY KEY  (`vid`,`field_name`,`delta`)
 ) TYPE=MyISAM;
 
+
+# date.module
+
 CREATE TABLE `node_field_date_data` (
   `vid` int unsigned NOT NULL default '0',
   `field_name` varchar(31) NOT NULL default '',
diff --git a/content.module b/content.module
index 78dd7ea3..a3d8510e 100644
--- a/content.module
+++ b/content.module
@@ -482,16 +482,20 @@ function _content_admin_field_add($type_name) {
   }
   if ($options) {
     $form = array();
-    $form['field_name'] = array(
+    $form['existing'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Add existing field'),
+    );
+    $form['existing']['field_name'] = array(
       '#type' => 'select',
       '#required' => TRUE,
       '#options' => $options,
     );
-    $form['submit'] = array(
+    $form['existing']['submit'] = array(
       '#type' => 'submit',
       '#value' => t('Add field'),
     );
-    $form['type_name'] = array(
+    $form['existing']['type_name'] = array(
       '#type' => 'value',
       '#value' => $type_name,
     );
@@ -499,7 +503,11 @@ function _content_admin_field_add($type_name) {
   }
   
   $form = array();
-  $form['label'] = array(
+  $form['new'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Create new field'),
+  );
+  $form['new']['label'] = array(
     '#title' => t('Label'),
     '#type' => 'textfield',
     '#default_value' => '',
@@ -510,16 +518,17 @@ function _content_admin_field_add($type_name) {
   foreach ($field_types as $field_name => $field_type) {
     $options[$field_name] = $field_type['label'];
   }
-  $form['type'] = array(
-    '#type' => 'select',
+  $form['new']['type'] = array(
+    '#type' => 'radios',
+    '#title' => t('Field type'),
     '#required' => TRUE,
     '#options' => $options,
   );
-  $form['submit'] = array(
+  $form['new']['submit'] = array(
     '#type' => 'submit',
     '#value' => t('Create field'),
   );
-  $form['type_name'] = array(
+  $form['new']['type_name'] = array(
     '#type' => 'value',
     '#value' => $type_name,
   );
diff --git a/date.module b/date.module
new file mode 100644
index 00000000..68990558
--- /dev/null
+++ b/date.module
@@ -0,0 +1,235 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Defines standard simple field types.
+ */
+
+/**
+ * Implementation of hook_help().
+ */
+function date_help($section) {
+  switch ($section) {
+    case 'admin/modules#description':
+      return t('Defines a date/time field type.');
+  }
+}
+
+/**
+ * Implementation of hook_field_info().
+ */
+function date_field_info() {
+  return array(
+    'date' => array('label' => 'Date'),
+  );
+}
+
+/**
+ * Implementation of hook_field_settings().
+ */
+function date_field_settings($op, $field, $scope) {
+  switch ($op) {
+    case 'form':
+      $form = array();
+      switch ($scope) {
+        case 'instance':
+          $options = array(
+            0 => t('Times are entered and displayed with site\'s time zone'),
+            1 => t('Times are entered and displayed with user\'s time zone'),
+          );
+          $form['time_zone'] = array(
+            '#type' => 'radios',
+            '#title' => t('Time zone handling'),
+            '#default_value' => $field['time_zone'] ? $field['time_zone'] : 0,
+            '#options' => $options,
+          );
+          break;
+        case 'global':
+          $options = array(
+            0 => t('Year'),
+            1 => t('Year and month'),
+            2 => t('Date'),
+            3 => t('Date and time'),
+            4 => t('Time only'),
+          );
+          $form['granularity'] = array(
+            '#type' => 'radios',
+            '#title' => t('Granularity'),
+            '#default_value' => $field['granularity'] ? $field['granularity'] : 0,
+            '#options' => $options,
+          );
+          break;
+      }
+      return $form;
+    
+    case 'validate':
+      break;
+
+    case 'save':
+      switch ($scope) {
+        case 'instance':
+          return array('time_zone');
+        case 'global':
+          return array('granularity');
+      }
+      break;
+  }
+}
+
+/**
+ * Implementation of hook_field().
+ */
+function date_field($op, $node, $field, $a2, $a3, $a4) {
+  switch ($op) {
+    case 'load':
+      $result = db_query("SELECT field_date FROM {node_field_date_data} WHERE vid = %d AND field_name = '%s' ORDER BY delta", $node->vid, $field['field_name']);
+      if ($field['multiple']) {
+        $values = array();
+        while ($value = db_fetch_object($result)) {
+          $values[] = array('value' => $value->field_date);
+        }
+        $additions = array($field['field_name'] => $values);
+      }
+      else {
+        $value = db_fetch_object($result);
+        $additions = array($field['field_name'] => array('value' => $value->field_date));
+      }
+      return $additions;
+
+    case 'view':
+      $output = '';
+      $node_field = $node->$field['field_name'];
+      if ($field['multiple']) {
+        foreach ($node_field as $delta => $item) {
+          $node_field[$delta]['view'] = check_plain($item['value']);
+        }
+      }
+      else {
+        $node_field['view'] = check_plain($node_field['value']);
+      }
+      $node->$field['field_name'] = $node_field;
+      if ($field['multiple']) {
+        $output = '';
+        foreach ($node_field as $delta => $item) {
+          $output .= '<div class="'. $field['field_name'] .'">'. $item['view'] .'</div>';
+        }
+        return $output;
+      }
+      else {
+        return '<div class="'. $field['field_name'] .'">'. $node_field['view'] .'</div>';
+      }
+
+    case 'form':
+      $form = array();
+      $node_field = $node->$field['field_name'];
+
+      $form[$field['field_name']] = array('#tree' => TRUE);
+
+      if ($field['multiple']) {
+        foreach (range(0, 2) as $delta) {
+          $form[$field['field_name']][$delta]['value'] = array(
+            '#type' => 'textfield',
+            '#title' => t($field['label']),
+            '#default_value' => $node_field[$delta]['value'],
+            '#required' => ($delta == 0) ? $field['required'] : FALSE,
+          );
+        }
+      }
+      else {
+        $form[$field['field_name']]['value'] = array(
+          '#type' => 'textfield',
+          '#title' => t($field['label']),
+          '#default_value' => $node_field['value'],
+          '#required' => $field['required'],
+        );
+      }
+      return $form;
+
+    case 'validate':
+      $node_field = $node->$field['field_name'];
+
+      if ($field['multiple']) {
+        if (is_array($node_field)) {
+          foreach ($node_field as $delta => $item) {
+            if ($item['value'] != '') {
+              if (preg_match('/[0-9]{8}T[0-9]{2}:[0-9]{2}:[0-9]{2}/', $item['value'])) {
+                form_set_error($field['field_name'] .']['. $delta .'][value', t('%name must be entered in ISO 8601 format (YYYYMMDDThh:mm:ss).', array('%name' => t($field['label']))));
+              }
+            }
+          }
+        }
+      }
+      else {
+        if (isset($node_field['value'])) {
+          if ($node_field['value'] != '') {
+            if (preg_match('/[0-9]{8}T[0-9]{2}:[0-9]{2}:[0-9]{2}/', $node_field['value'])) {
+              form_set_error($field['field_name'] .'][value', t('%name must be entered in ISO 8601 format (YYYYMMDDThh:mm:ss).', array('%name' => t($field['label']))));
+            }
+          }
+        }
+      }
+      return;
+
+    case 'insert':
+      $node_field = $node->$field['field_name'];
+      if ($field['multiple']) {
+        foreach ($node_field as $delta => $item) {
+          db_query("INSERT INTO {node_field_date_data} (vid, field_name, delta, field_date) VALUES (%d, '%s', %d, '%s')", $node->vid, $field['field_name'], $delta, $item['value']);
+        }
+      }
+      else {
+        db_query("INSERT INTO {node_field_date_data} (vid, field_name, field_date) VALUES (%d, '%s', '%s')", $node->vid, $field['field_name'], $node_field['value']);
+      }
+      return;
+
+    case 'update':
+      $node_field = $node->$field['field_name'];
+      // Delete and insert, rather than update, in case a field was added.
+      db_query("DELETE FROM {node_field_date_data} WHERE vid = %d AND field_name = '%s'", $node->vid, $field['field_name']);
+      if ($field['multiple']) {
+        foreach ($node_field as $delta => $item) {
+          db_query("INSERT INTO {node_field_date_data} (vid, field_name, delta, field_date) VALUES (%d, '%s', %d, '%s')", $node->vid, $field['field_name'], $delta, $item['value']);
+        }
+      }
+      else {
+        db_query("INSERT INTO {node_field_date_data} (vid, field_name, field_date) VALUES (%d, '%s', '%s')", $node->vid, $field['field_name'], $node_field['value']);
+      }
+      return;
+
+    case 'delete':
+      db_query("DELETE FROM {node_field_date_data} WHERE vid = %d AND field_name = '%s'", $node->vid, $field['field_name']);
+      return;
+  }
+}
+
+/**
+ * Implementation of hook_field_query().
+ */
+function date_field_query($field, $op, $value) {
+  $query_additions = array();
+
+  switch ($op) {
+    case 'is':
+      $query_additions['tables'] = array('%table' => 'node_field_date_data');
+      $query_additions['where'] = "%table.field_date = '%s'";
+      $query_additions['data'] = array($value);
+      break;
+
+    case 'after':
+      $query_additions['tables'] = array('%table' => 'node_field_date_data');
+      $query_additions['where'] = "%table.field_date > '%s'";
+      $query_additions['data'] = array($value);
+      break;
+
+    case 'before':
+      $query_additions['tables'] = array('%table' => 'node_field_date_data');
+      $query_additions['where'] = "%table.field_date < '%s'";
+      $query_additions['data'] = array($value);
+      break;
+  }
+
+  return $query_additions;
+}
+
+?>
\ No newline at end of file
diff --git a/field.module b/field.module
deleted file mode 100644
index e9151bc9..00000000
--- a/field.module
+++ /dev/null
@@ -1,701 +0,0 @@
-<?php
-// $Id$
-
-/**
- * @file
- * Defines standard simple field types.
- */
-
-/**
- * Implementation of hook_help().
- */
-function field_help($section) {
-  switch ($section) {
-    case 'admin/modules#description':
-      return t('Defines standard simple field types.');
-  }
-}
-
-/**
- * Implementation of hook_field_info().
- */
-function field_field_info() {
-  return array(
-    'field_shorttext' => array('label' => 'Short Text'),
-    'field_longtext' => array('label' => 'Long Text'),
-    'field_integer' => array('label' => 'Integer'),
-    'field_decimal' => array('label' => 'Decimal'),
-    'field_date' => array('label' => 'Date'),
-  );
-}
-
-/**
- * Implementation of hook_field_settings().
- */
-function field_field_settings($op, $field, $scope) {
-  switch ($op) {
-    case 'form':
-      $form = array();
-      switch ($field['type']) {
-        case 'field_shorttext':
-        case 'field_longtext':
-          switch ($scope) {
-            case 'instance':
-              $form['rows'] = array(
-                '#type' => 'textfield',
-                '#title' => t('Rows'),
-                '#default_value' => $field['rows'] ? $field['rows'] : 1,
-                '#required' => TRUE,
-              );
-              break;
-
-            case 'global':
-              $options = array(0 => t('Plain text'), 1 => t('Filtered text (user selects input format)'));
-              $form['text_processing'] = array(
-                '#type' => 'radios',
-                '#title' => t('Text processing'),
-                '#default_value' => $field['text_processing'] ? $field['text_processing'] : 0,
-                '#options' => $options,
-              );
-              break;
-          }
-          break;
-        case 'field_integer':
-        case 'field_decimal':
-          switch ($scope) {
-            case 'global':
-              $form['min'] = array(
-                '#type' => 'textfield',
-                '#title' => t('Minimum'),
-                '#default_value' => $field['min'] ? $field['min'] : '',
-              );
-              $form['max'] = array(
-                '#type' => 'textfield',
-                '#title' => t('Maximum'),
-                '#default_value' => $field['min'] ? $field['min'] : '',
-              );
-              break;
-          }
-          break;
-        case 'field_date':
-          switch ($scope) {
-            case 'instance':
-              $options = array(
-                0 => t('Times are entered and displayed with site\'s time zone'),
-                1 => t('Times are entered and displayed with user\'s time zone'),
-              );
-              $form['time_zone'] = array(
-                '#type' => 'radios',
-                '#title' => t('Time zone handling'),
-                '#default_value' => $field['time_zone'] ? $field['time_zone'] : 0,
-                '#options' => $options,
-              );
-              break;
-            case 'global':
-              $options = array(
-                0 => t('Year'),
-                1 => t('Year and month'),
-                2 => t('Date'),
-                3 => t('Date and time'),
-                4 => t('Time only'),
-              );
-              $form['granularity'] = array(
-                '#type' => 'radios',
-                '#title' => t('Granularity'),
-                '#default_value' => $field['granularity'] ? $field['granularity'] : 0,
-                '#options' => $options,
-              );
-              break;
-          }
-          break;
-      }
-      return $form;
-    
-    case 'validate':
-      switch ($field['type']) {
-        case 'field_shorttext':
-        case 'field_longtext':
-          switch ($scope) {
-            case 'instance':
-              if (!is_numeric($field['rows']) || intval($field['rows']) != $field['rows'] || $field['rows'] <= 0) {
-                form_set_error('rows', t('"Rows" must be a positive integer.'));
-              }
-              break;
-          }
-        break;
-        case 'field_integer':
-        case 'field_decimal':
-          switch ($scope) {
-            case 'global':
-              if ($field['min'] && !is_numeric($field['min'])) {
-                form_set_error('rows', t('"Minimum" must be a number.'));
-              }
-              if ($field['max'] && !is_numeric($field['max'])) {
-                form_set_error('rows', t('"Maximum" must be a number.'));
-              }
-              break;
-          }
-          break;
-        case 'field_date':
-          break;
-      }
-      break;
-
-    case 'save':
-      switch ($field['type']) {
-        case 'field_shorttext':
-        case 'field_longtext':
-          switch ($scope) {
-            case 'instance':
-              return array('rows');
-            case 'global':
-              return array('text_processing');
-          }
-          break;
-        case 'field_integer':
-        case 'field_decimal':
-          switch ($scope) {
-            case 'instance':
-              return array();
-            case 'global':
-              return array('min', 'max');
-          }
-          break;
-        case 'field_date':
-          switch ($scope) {
-            case 'instance':
-              return array('time_zone');
-            case 'global':
-              return array('granularity');
-          }
-          break;
-      }
-    break;
-  }
-}
-
-/**
- * Implementation of hook_field().
- */
-function field_field($op, $node, $field, $a2, $a3, $a4) {
-  switch ($op) {
-    case 'load':
-      switch($field['type']) {
-        case 'field_shorttext':
-          $result = db_query("SELECT field_shorttext, format FROM {node_field_shorttext_data} WHERE vid = %d AND field_name = '%s' ORDER BY delta", $node->vid, $field['field_name']);
-          if ($field['multiple']) {
-            $values = array();
-            while ($value = db_fetch_object($result)) {
-              $values[] = array('value' => $value->field_shorttext, 'format' => $value->format);
-            }
-            $additions = array($field['field_name'] => $values);
-          }
-          else {
-            $value = db_fetch_object($result);
-            $additions = array($field['field_name'] => array('value' => $value->field_shorttext, 'format' => $value->format));
-          }
-          break;
-        case 'field_longtext':
-          $result = db_query("SELECT field_longtext, format FROM {node_field_longtext_data} WHERE vid = %d AND field_name = '%s' ORDER BY delta", $node->vid, $field['field_name']);
-          if ($field['multiple']) {
-            $values = array();
-            while ($value = db_fetch_object($result)) {
-              $values[] = array('value' => $value->field_longtext, 'format' => $value->format);
-            }
-            $additions = array($field['field_name'] => $values);
-          }
-          else {
-            $value = db_fetch_object($result);
-            $additions = array($field['field_name'] => array('value' => $value->field_longtext, 'format' => $value->format));
-          }
-          break;
-        case 'field_integer':
-          $result = db_query("SELECT field_int FROM {node_field_int_data} WHERE vid = %d AND field_name = '%s' ORDER BY delta", $node->vid, $field['field_name']);
-          if ($field['multiple']) {
-            $values = array();
-            while ($value = db_fetch_object($result)) {
-              $values[] = array('value' => $value->field_int);
-            }
-            $additions = array($field['field_name'] => $values);
-          }
-          else {
-            $value = db_fetch_object($result);
-            $additions = array($field['field_name'] => array('value' => $value->field_int));
-          }
-          break;
-        case 'field_decimal':
-          $result = db_query("SELECT field_float FROM {node_field_float_data} WHERE vid = %d AND field_name = '%s' ORDER BY delta", $node->vid, $field['field_name']);
-          if ($field['multiple']) {
-            $values = array();
-            while ($value = db_fetch_object($result)) {
-              $values[] = array('value' => $value->field_int);
-            }
-            $additions = array($field['field_name'] => $values);
-          }
-          else {
-            $value = db_fetch_object($result);
-            $additions = array($field['field_name'] => array('value' => $value->field_float));
-          }
-          break;
-        case 'field_date':
-          $result = db_query("SELECT field_date FROM {node_field_date_data} WHERE vid = %d AND field_name = '%s' ORDER BY delta", $node->vid, $field['field_name']);
-          if ($field['multiple']) {
-            $values = array();
-            while ($value = db_fetch_object($result)) {
-              $values[] = array('value' => $value->field_date);
-            }
-            $additions = array($field['field_name'] => $values);
-          }
-          else {
-            $value = db_fetch_object($result);
-            $additions = array($field['field_name'] => array('value' => $value->field_date));
-          }
-          break;
-      }
-      return $additions;
-
-    case 'view':
-      $output = '';
-      $node_field = $node->$field['field_name'];
-      switch($field['type']) {
-        case 'field_shorttext':
-        case 'field_longtext':
-          if ($field['multiple']) {
-            foreach ($node_field as $delta => $item) {
-              if ($field['text_processing']) {
-                $node_field[$delta]['view'] = check_markup($item['value'], $item['format'], isset($node->in_preview) ? $node->in_preview : FALSE);
-              }
-              else {
-                $node_field[$delta]['view'] = check_plain($item['value']);
-              }
-            }
-          }
-          else {
-            if ($field['text_processing']) {
-              $node_field['view'] = check_markup($node_field['value'], $node_field['format'], isset($node->in_preview) ? $node->in_preview : FALSE);
-            }
-            else {
-              $node_field['view'] = check_plain($node_field['value']);
-            }
-          }
-          break;
-        case 'field_integer':
-        case 'field_decimal':
-          if ($field['multiple']) {
-            foreach ($node_field as $delta => $item) {
-              $node_field[$delta]['view'] = check_plain($item['value']);
-            }
-          }
-          else {
-            $node_field['view'] = check_plain($node_field['value']);
-          }
-          break;
-        case 'field_date':
-          if ($field['multiple']) {
-            foreach ($node_field as $delta => $item) {
-              $node_field[$delta]['view'] = check_plain($item['value']);
-            }
-          }
-          else {
-            $node_field['view'] = check_plain($node_field['value']);
-          }
-          break;
-      }
-      $node->$field['field_name'] = $node_field;
-      if ($field['multiple']) {
-        $output = '';
-        foreach ($node_field as $delta => $item) {
-          $output .= '<div class="'. $field['field_name'] .'">'. $item['view'] .'</div>';
-        }
-        return $output;
-      }
-      else {
-        return '<div class="'. $field['field_name'] .'">'. $node_field['view'] .'</div>';
-      }
-
-    case 'form':
-      $form = array();
-      $node_field = $node->$field['field_name'];
-
-      $form[$field['field_name']] = array('#tree' => TRUE);
-
-      switch($field['type']) {
-        case 'field_shorttext':
-        case 'field_longtext':
-          if ($field['multiple']) {
-            foreach (range(0, 2) as $delta) {
-              if ($field['rows'] == 1) {
-                $form[$field['field_name']][$delta]['value'] = array(
-                  '#type' => 'textfield',
-                  '#title' => t($field['label']),
-                  '#default_value' => $node_field[$delta]['value'],
-                  '#required' => ($delta == 0) ? $field['required'] : FALSE,
-                );
-              }
-              else {
-                $form[$field['field_name']][$delta]['value'] = array(
-                  '#type' => 'textarea',
-                  '#title' => t($field['label']),
-                  '#default_value' => $node_field[$delta]['value'],
-                  '#required' => ($delta == 0) ? $field['required'] : FALSE,
-                  '#rows' => $field['rows'],
-                );
-              }
-              if ($field['text_processing']) {
-                $form[$field['field_name']][$delta] = array_merge($form[$field['field_name']][$delta], filter_form($node_field[$delta]['format']));
-              }
-            }
-          }
-          else {
-            if ($field['rows'] == 1) {
-              $form[$field['field_name']]['value'] = array(
-                '#type' => 'textfield',
-                '#title' => t($field['label']),
-                '#default_value' => $node_field['value'],
-                '#required' => $field['required'],
-              );
-            }
-            else {
-              $form[$field['field_name']]['value'] = array(
-                '#type' => 'textarea',
-                '#title' => t($field['label']),
-                '#default_value' => $node_field['value'],
-                '#required' => $field['required'],
-                '#rows' => $field['rows'],
-              );
-            }
-            if ($field['text_processing']) {
-              $form[$field['field_name']] = array_merge($form[$field['field_name']], filter_form($node_field['format']));
-            }
-          }
-          break;
-        case 'field_integer':
-        case 'field_decimal':
-          if ($field['multiple']) {
-            foreach (range(0, 2) as $delta) {
-              $form[$field['field_name']][$delta]['value'] = array(
-                '#type' => 'textfield',
-                '#title' => t($field['label']),
-                '#default_value' => $node_field[$delta]['value'],
-                '#required' => ($delta == 0) ? $field['required'] : FALSE,
-              );
-            }
-          }
-          else {
-            $form[$field['field_name']]['value'] = array(
-              '#type' => 'textfield',
-              '#title' => t($field['label']),
-              '#default_value' => $node_field['value'],
-              '#required' => $field['required'],
-            );
-          }
-          break;
-        case 'field_date':
-          if ($field['multiple']) {
-            foreach (range(0, 2) as $delta) {
-              $form[$field['field_name']][$delta]['value'] = array(
-                '#type' => 'textfield',
-                '#title' => t($field['label']),
-                '#default_value' => $node_field[$delta]['value'],
-                '#required' => ($delta == 0) ? $field['required'] : FALSE,
-              );
-            }
-          }
-          else {
-            $form[$field['field_name']]['value'] = array(
-              '#type' => 'textfield',
-              '#title' => t($field['label']),
-              '#default_value' => $node_field['value'],
-              '#required' => $field['required'],
-            );
-          }
-          break;
-      }
-      return $form;
-
-    case 'validate':
-      $node_field = $node->$field['field_name'];
-
-      switch($field['type']) {
-        case 'field_shorttext':
-        case 'field_longtext':
-          break;
-        case 'field_integer':
-        case 'field_decimal':
-          if ($field['multiple']) {
-            if (is_array($node_field)) {
-              foreach ($node_field as $delta => $item) {
-                if ($item['value'] != '') {
-                  if (is_numeric($field['min']) && $item['value'] < $field['min']) {
-                    form_set_error($field['field_name'] .']['. $delta .'][value', t('The value of %name may be no smaller than %min.', array('%name' => t($field['label']), '%min' => $field['min'])));
-                  }
-                  if (is_numeric($field['max']) && $item['value'] > $field['max']) {
-                    form_set_error($field['field_name'] .']['. $delta .'][value', t('The value of %name may be no larger than %max.', array('%name' => t($field['label']), '%max' => $field['max'])));
-                  }
-                }
-              }
-            }
-          }
-          else {
-            if (isset($node_field['value'])) {
-              if ($node_field['value'] != '') {
-                if (is_numeric($field['min']) && $node_field['value'] < $field['min']) {
-                  form_set_error($field['field_name'] .'][value', t('The value of %name may be no smaller than %min.', array('%name' => t($field['label']), '%min' => $field['min'])));
-                }
-                if (is_numeric($field['max']) && $node_field['value'] > $field['max']) {
-                  form_set_error($field['field_name'] .'][value', t('The value of %name may be no larger than %max.', array('%name' => t($field['label']), '%max' => $field['max'])));
-                }
-              }
-            }
-          }
-          break;
-        case 'field_date':
-          if ($field['multiple']) {
-            if (is_array($node_field)) {
-              foreach ($node_field as $delta => $item) {
-                if ($item['value'] != '') {
-                  if (preg_match('/[0-9]{8}T[0-9]{2}:[0-9]{2}:[0-9]{2}/', $item['value'])) {
-                    form_set_error($field['field_name'] .']['. $delta .'][value', t('%name must be entered in ISO 8601 format (YYYYMMDDThh:mm:ss).', array('%name' => t($field['label']))));
-                  }
-                }
-              }
-            }
-          }
-          else {
-            if (isset($node_field['value'])) {
-              if ($node_field['value'] != '') {
-                if (preg_match('/[0-9]{8}T[0-9]{2}:[0-9]{2}:[0-9]{2}/', $node_field['value'])) {
-                  form_set_error($field['field_name'] .'][value', t('%name must be entered in ISO 8601 format (YYYYMMDDThh:mm:ss).', array('%name' => t($field['label']))));
-                }
-              }
-            }
-          }
-          break;
-      }
-      return;
-
-    case 'insert':
-      $node_field = $node->$field['field_name'];
-      switch($field['type']) {
-        case 'field_shorttext':
-          if ($field['multiple']) {
-            foreach ($node_field as $delta => $item) {
-              db_query("INSERT INTO {node_field_shorttext_data} (vid, field_name, delta, field_shorttext, format) VALUES (%d, '%s', %d, '%s', %d)", $node->vid, $field['field_name'], $delta, $item['value'], $item['format']);
-            }
-          }
-          else {
-            db_query("INSERT INTO {node_field_shorttext_data} (vid, field_name, field_shorttext, format) VALUES (%d, '%s', '%s', %d)", $node->vid, $field['field_name'], $node_field['value'], $node_field['format']);
-          }
-          break;
-        case 'field_longtext':
-          if ($field['multiple']) {
-            foreach ($node_field as $delta => $item) {
-              db_query("INSERT INTO {node_field_longtext_data} (vid, field_name, delta, field_longtext, format) VALUES (%d, '%s', %d, '%s', %d)", $node->vid, $field['field_name'], $delta, $item['value'], $item['format']);
-            }
-          }
-          else {
-            db_query("INSERT INTO {node_field_longtext_data} (vid, field_name, field_longtext, format) VALUES (%d, '%s', '%s', %d)", $node->vid, $field['field_name'], $node_field['value'], $node_field['format']);
-          }
-          break;
-        case 'field_integer':
-          if ($field['multiple']) {
-            foreach ($node_field as $delta => $item) {
-              db_query("INSERT INTO {node_field_int_data} (vid, field_name, delta, field_int) VALUES (%d, '%s', %d, %d)", $node->vid, $field['field_name'], $delta, $item['value']);
-            }
-          }
-          else {
-            db_query("INSERT INTO {node_field_int_data} (vid, field_name, field_int) VALUES (%d, '%s', %d)", $node->vid, $field['field_name'], $node_field['value']);
-          }
-          break;
-        case 'field_decimal':
-          if ($field['multiple']) {
-            foreach ($node_field as $delta => $item) {
-              db_query("INSERT INTO {node_field_float_data} (vid, field_name, delta, field_float) VALUES (%d, '%s', %d, %d)", $node->vid, $field['field_name'], $delta, $item['value']);
-            }
-          }
-          else {
-            db_query("INSERT INTO {node_field_float_data} (vid, field_name, field_float) VALUES (%d, '%s', %d)", $node->vid, $field['field_name'], $node_field['value']);
-          }
-          break;
-        case 'field_date':
-          if ($field['multiple']) {
-            foreach ($node_field as $delta => $item) {
-              db_query("INSERT INTO {node_field_date_data} (vid, field_name, delta, field_date) VALUES (%d, '%s', %d, '%s')", $node->vid, $field['field_name'], $delta, $item['value']);
-            }
-          }
-          else {
-            db_query("INSERT INTO {node_field_date_data} (vid, field_name, field_date) VALUES (%d, '%s', '%s')", $node->vid, $field['field_name'], $node_field['value']);
-          }
-          break;
-      }
-      return;
-
-    case 'update':
-      $node_field = $node->$field['field_name'];
-      // Delete and insert, rather than update, in case a field was added.
-      switch($field['type']) {
-        case 'field_shorttext':
-          db_query("DELETE FROM {node_field_shorttext_data} WHERE vid = %d AND field_name = '%s'", $node->vid, $field['field_name']);
-          if ($field['multiple']) {
-            foreach ($node_field as $delta => $item) {
-              db_query("INSERT INTO {node_field_shorttext_data} (vid, field_name, delta, field_shorttext, format) VALUES (%d, '%s', %d, '%s', %d)", $node->vid, $field['field_name'], $delta, $item['value'], $item['format']);
-            }
-          }
-          else {
-            db_query("INSERT INTO {node_field_shorttext_data} (vid, field_name, field_shorttext, format) VALUES (%d, '%s', '%s', %d)", $node->vid, $field['field_name'], $node_field['value'], $node_field['format']);
-          }
-          break;
-        case 'field_longtext':
-          db_query("DELETE FROM {node_field_longtext_data} WHERE vid = %d AND field_name = '%s'", $node->vid, $field['field_name']);
-          if ($field['multiple']) {
-            foreach ($node_field as $delta => $item) {
-              db_query("INSERT INTO {node_field_longtext_data} (vid, field_name, delta, field_longtext, format) VALUES (%d, '%s', %d, '%s', %d)", $node->vid, $field['field_name'], $delta, $item['value'], $item['format']);
-            }
-          }
-          else {
-            db_query("INSERT INTO {node_field_longtext_data} (vid, field_name, field_longtext, format) VALUES (%d, '%s', '%s', %d)", $node->vid, $field['field_name'], $node_field['value'], $node_field['format']);
-          }
-          break;
-        case 'field_integer':
-          db_query("DELETE FROM {node_field_int_data} WHERE vid = %d AND field_name = '%s'", $node->vid, $field['field_name']);
-          if ($field['multiple']) {
-            foreach ($node_field as $delta => $item) {
-              db_query("INSERT INTO {node_field_int_data} (vid, field_name, delta, field_int) VALUES (%d, '%s', %d, %d)", $node->vid, $field['field_name'], $delta, $item['value']);
-            }
-          }
-          else {
-            db_query("INSERT INTO {node_field_int_data} (vid, field_name, field_int) VALUES (%d, '%s', %d)", $node->vid, $field['field_name'], $node_field['value']);
-          }
-          break;
-        case 'field_decimal':
-          db_query("DELETE FROM {node_field_float_data} WHERE vid = %d AND field_name = '%s'", $node->vid, $field['field_name']);
-          if ($field['multiple']) {
-            foreach ($node_field as $delta => $item) {
-              db_query("INSERT INTO {node_field_float_data} (vid, field_name, delta, field_float) VALUES (%d, '%s', %d, %d)", $node->vid, $field['field_name'], $delta, $item['value']);
-            }
-          }
-          else {
-            db_query("INSERT INTO {node_field_float_data} (vid, field_name, field_float) VALUES (%d, '%s', %d)", $node->vid, $field['field_name'], $node_field['value']);
-          }
-          break;
-        case 'field_date':
-          db_query("DELETE FROM {node_field_date_data} WHERE vid = %d AND field_name = '%s'", $node->vid, $field['field_name']);
-          if ($field['multiple']) {
-            foreach ($node_field as $delta => $item) {
-              db_query("INSERT INTO {node_field_date_data} (vid, field_name, delta, field_date) VALUES (%d, '%s', %d, '%s')", $node->vid, $field['field_name'], $delta, $item['value']);
-            }
-          }
-          else {
-            db_query("INSERT INTO {node_field_date_data} (vid, field_name, field_date) VALUES (%d, '%s', '%s')", $node->vid, $field['field_name'], $node_field['value']);
-          }
-          break;
-      }
-      return;
-
-    case 'delete':
-      switch($field['type']) {
-        case 'field_shorttext':
-          db_query("DELETE FROM {node_field_shorttext_data} WHERE vid = %d AND field_name = '%s'", $node->vid, $field['field_name']);
-          break;
-        case 'field_longtext':
-          db_query("DELETE FROM {node_field_longtext_data} WHERE vid = %d AND field_name = '%s'", $node->vid, $field['field_name']);
-          break;
-        case 'field_integer':
-          db_query("DELETE FROM {node_field_int_data} WHERE vid = %d AND field_name = '%s'", $node->vid, $field['field_name']);
-          break;
-        case 'field_decimal':
-          db_query("DELETE FROM {node_field_float_data} WHERE vid = %d AND field_name = '%s'", $node->vid, $field['field_name']);
-          break;
-        case 'field_date':
-          db_query("DELETE FROM {node_field_date_data} WHERE vid = %d AND field_name = '%s'", $node->vid, $field['field_name']);
-          break;
-      }
-      return;
-  }
-}
-
-/**
- * Implementation of hook_field_query().
- */
-function field_field_query($field, $op, $value) {
-  $query_additions = array();
-
-  switch ($field['type']) {
-    case 'field_shorttext':
-    case 'field_longtext':
-      $table_name = ($field['type'] == 'field_shorttext' ? 'node_field_shorttext_data' : 'node_field_longtext_data');
-      $column_name = ($field['type'] == 'field_shorttext' ? 'field_shorttext' : 'field_longtext');
-
-      switch ($op) {
-        case 'is':
-          $query_additions['tables'] = array('%table' => $table_name);
-          $query_additions['where'] = "%table.". $column_name ." = '%s'";
-          $query_additions['data'] = array($value);
-          break;
-
-        case 'contains':
-          $query_additions['tables'] = array('%table' => $table_name);
-          $query_additions['where'] = "%table.". $column_name ." LIKE '%%%s%%'";
-          $query_additions['data'] = array($value);
-          break;
-
-        case 'like':
-          $query_additions['tables'] = array('%table' => $table_name);
-          $query_additions['where'] = "%table.". $column_name ." LIKE '%s'";
-          $query_additions['data'] = array($value);
-          break;
-      }
-      break;
-
-    case 'field_integer':
-    case 'field_decimal':
-      $table_name = ($field['type'] == 'field_integer' ? 'node_field_int_data' : 'node_field_float_data');
-      $column_name = ($field['type'] == 'field_integer' ? 'field_int' : 'field_float');
-
-      switch ($op) {
-        case 'is':
-          $query_additions['tables'] = array('%table' => $table_name);
-          $query_additions['where'] = "%table.". $column_name ." = %d";
-          $query_additions['data'] = array($value);
-          break;
-
-        case 'over':
-          $query_additions['tables'] = array('%table' => $table_name);
-          $query_additions['where'] = "%table.". $column_name ." > %d";
-          $query_additions['data'] = array($value);
-          break;
-
-        case 'under':
-          $query_additions['tables'] = array('%table' => $table_name);
-          $query_additions['where'] = "%table.". $column_name ." < %d";
-          $query_additions['data'] = array($value);
-          break;
-      }
-
-    case 'field_date':
-      switch ($op) {
-        case 'is':
-          $query_additions['tables'] = array('%table' => 'node_field_date_data');
-          $query_additions['where'] = "%table.field_date = '%s'";
-          $query_additions['data'] = array($value);
-          break;
-
-        case 'after':
-          $query_additions['tables'] = array('%table' => 'node_field_date_data');
-          $query_additions['where'] = "%table.field_date > '%s'";
-          $query_additions['data'] = array($value);
-          break;
-
-        case 'before':
-          $query_additions['tables'] = array('%table' => 'node_field_date_data');
-          $query_additions['where'] = "%table.field_date < '%s'";
-          $query_additions['data'] = array($value);
-          break;
-      }
-      break;
-  }
-
-  return $query_additions;
-}
-
-?>
\ No newline at end of file
diff --git a/list.module b/list.module
index 904ef6ef..7f724c50 100644
--- a/list.module
+++ b/list.module
@@ -26,9 +26,6 @@ function list_menu($may_cache) {
     $items[] = array('path' => 'list', 'title' => t('list'),
       'callback' => 'list_page', 'access' => user_access('access content'),
       'type' => MENU_CALLBACK);
-    $items[] = array('path' => 'list/titles', 'title' => t('list'),
-      'callback' => 'list_page', 'access' => user_access('access content'),
-      'type' => MENU_CALLBACK);
   }
 
   return $items;
@@ -42,11 +39,6 @@ function list_page() {
 
   $arguments = explode('/', $_GET['q']);
   array_shift($arguments);
-  
-  if ($arguments[0] == 'titles') {
-    $titles_only = TRUE;
-    array_shift($arguments); 
-  }
 
   $conditions = array();
   $sort = array();
@@ -59,22 +51,14 @@ function list_page() {
     $conditions[] = array('field' => $field, 'op' => $op, 'value' => $value);
   }
 
-  if ($titles_only) {
-    $header = array('title');
-    $result = content_node_query($conditions, $sort, 'n.nid, n.title');
-    while ($node = db_fetch_object($result)) {
-      $rows[] = l($node->title, drupal_get_path_alias("node/$node->nid'")); 
-    }
-    $output = theme('node_list', $rows);
-  }
-  else {
-    $result = content_node_query($conditions, $sort);
-    while ($node = db_fetch_array($result)) {
-      $node = node_load($node);
-      $output .= node_view($node);
-    }
+  $result = content_node_query($conditions, $sort);
+
+  while ($node = db_fetch_object($result)) {
+    $node = node_load($node->nid);
+    $output .= node_view($node);
   }
-  print theme('page', $output);
+
+  return $output;
 }
 
 ?>
\ No newline at end of file
diff --git a/number.module b/number.module
new file mode 100644
index 00000000..46020b0b
--- /dev/null
+++ b/number.module
@@ -0,0 +1,296 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Defines standard simple field types.
+ */
+
+/**
+ * Implementation of hook_help().
+ */
+function number_help($section) {
+  switch ($section) {
+    case 'admin/modules#description':
+      return t('Defines numeric field types.');
+  }
+}
+
+/**
+ * Implementation of hook_field_info().
+ */
+function number_field_info() {
+  return array(
+    'number_integer' => array('label' => 'Integer'),
+    'number_decimal' => array('label' => 'Decimal'),
+  );
+}
+
+/**
+ * Implementation of hook_field_settings().
+ */
+function number_field_settings($op, $field, $scope) {
+  switch ($op) {
+    case 'form':
+      $form = array();
+      switch ($scope) {
+        case 'global':
+          $form['min'] = array(
+            '#type' => 'textfield',
+            '#title' => t('Minimum'),
+            '#default_value' => $field['min'] ? $field['min'] : '',
+          );
+          $form['max'] = array(
+            '#type' => 'textfield',
+            '#title' => t('Maximum'),
+            '#default_value' => $field['min'] ? $field['min'] : '',
+          );
+          break;
+      }
+      return $form;
+    
+    case 'validate':
+      switch ($scope) {
+        case 'global':
+          if ($field['min'] && !is_numeric($field['min'])) {
+            form_set_error('rows', t('"Minimum" must be a number.'));
+          }
+          if ($field['max'] && !is_numeric($field['max'])) {
+            form_set_error('rows', t('"Maximum" must be a number.'));
+          }
+          break;
+      }
+      break;
+
+    case 'save':
+      switch ($scope) {
+        case 'instance':
+          return array();
+        case 'global':
+          return array('min', 'max');
+      }
+      break;
+  }
+}
+
+/**
+ * Implementation of hook_field().
+ */
+function number_field($op, $node, $field, $a2, $a3, $a4) {
+  switch ($op) {
+    case 'load':
+      switch($field['type']) {
+        case 'number_integer':
+          $result = db_query("SELECT field_int FROM {node_field_int_data} WHERE vid = %d AND field_name = '%s' ORDER BY delta", $node->vid, $field['field_name']);
+          if ($field['multiple']) {
+            $values = array();
+            while ($value = db_fetch_object($result)) {
+              $values[] = array('value' => $value->field_int);
+            }
+            $additions = array($field['field_name'] => $values);
+          }
+          else {
+            $value = db_fetch_object($result);
+            $additions = array($field['field_name'] => array('value' => $value->field_int));
+          }
+          break;
+        case 'number_decimal':
+          $result = db_query("SELECT field_float FROM {node_field_float_data} WHERE vid = %d AND field_name = '%s' ORDER BY delta", $node->vid, $field['field_name']);
+          if ($field['multiple']) {
+            $values = array();
+            while ($value = db_fetch_object($result)) {
+              $values[] = array('value' => $value->field_int);
+            }
+            $additions = array($field['field_name'] => $values);
+          }
+          else {
+            $value = db_fetch_object($result);
+            $additions = array($field['field_name'] => array('value' => $value->field_float));
+          }
+          break;
+      }
+      return $additions;
+
+    case 'view':
+      $output = '';
+      $node_field = $node->$field['field_name'];
+
+      if ($field['multiple']) {
+        foreach ($node_field as $delta => $item) {
+          $node_field[$delta]['view'] = check_plain($item['value']);
+        }
+      }
+      else {
+        $node_field['view'] = check_plain($node_field['value']);
+      }
+
+      $node->$field['field_name'] = $node_field;
+      if ($field['multiple']) {
+        $output = '';
+        foreach ($node_field as $delta => $item) {
+          $output .= '<div class="'. $field['field_name'] .'">'. $item['view'] .'</div>';
+        }
+        return $output;
+      }
+      else {
+        return '<div class="'. $field['field_name'] .'">'. $node_field['view'] .'</div>';
+      }
+
+    case 'form':
+      $form = array();
+      $node_field = $node->$field['field_name'];
+
+      $form[$field['field_name']] = array('#tree' => TRUE);
+
+      if ($field['multiple']) {
+        foreach (range(0, 2) as $delta) {
+          $form[$field['field_name']][$delta]['value'] = array(
+            '#type' => 'textfield',
+            '#title' => t($field['label']),
+            '#default_value' => $node_field[$delta]['value'],
+            '#required' => ($delta == 0) ? $field['required'] : FALSE,
+          );
+        }
+      }
+      else {
+        $form[$field['field_name']]['value'] = array(
+          '#type' => 'textfield',
+          '#title' => t($field['label']),
+          '#default_value' => $node_field['value'],
+          '#required' => $field['required'],
+        );
+      }
+      return $form;
+
+    case 'validate':
+      $node_field = $node->$field['field_name'];
+
+      if ($field['multiple']) {
+        if (is_array($node_field)) {
+          foreach ($node_field as $delta => $item) {
+            if ($item['value'] != '') {
+              if (is_numeric($field['min']) && $item['value'] < $field['min']) {
+                form_set_error($field['field_name'] .']['. $delta .'][value', t('The value of %name may be no smaller than %min.', array('%name' => t($field['label']), '%min' => $field['min'])));
+              }
+              if (is_numeric($field['max']) && $item['value'] > $field['max']) {
+                form_set_error($field['field_name'] .']['. $delta .'][value', t('The value of %name may be no larger than %max.', array('%name' => t($field['label']), '%max' => $field['max'])));
+              }
+            }
+          }
+        }
+      }
+      else {
+        if (isset($node_field['value'])) {
+          if ($node_field['value'] != '') {
+            if (is_numeric($field['min']) && $node_field['value'] < $field['min']) {
+              form_set_error($field['field_name'] .'][value', t('The value of %name may be no smaller than %min.', array('%name' => t($field['label']), '%min' => $field['min'])));
+            }
+            if (is_numeric($field['max']) && $node_field['value'] > $field['max']) {
+              form_set_error($field['field_name'] .'][value', t('The value of %name may be no larger than %max.', array('%name' => t($field['label']), '%max' => $field['max'])));
+            }
+          }
+        }
+      }
+      return;
+
+    case 'insert':
+      $node_field = $node->$field['field_name'];
+      switch($field['type']) {
+        case 'number_integer':
+          if ($field['multiple']) {
+            foreach ($node_field as $delta => $item) {
+              db_query("INSERT INTO {node_field_int_data} (vid, field_name, delta, field_int) VALUES (%d, '%s', %d, %d)", $node->vid, $field['field_name'], $delta, $item['value']);
+            }
+          }
+          else {
+            db_query("INSERT INTO {node_field_int_data} (vid, field_name, field_int) VALUES (%d, '%s', %d)", $node->vid, $field['field_name'], $node_field['value']);
+          }
+          break;
+        case 'number_decimal':
+          if ($field['multiple']) {
+            foreach ($node_field as $delta => $item) {
+              db_query("INSERT INTO {node_field_float_data} (vid, field_name, delta, field_float) VALUES (%d, '%s', %d, %d)", $node->vid, $field['field_name'], $delta, $item['value']);
+            }
+          }
+          else {
+            db_query("INSERT INTO {node_field_float_data} (vid, field_name, field_float) VALUES (%d, '%s', %d)", $node->vid, $field['field_name'], $node_field['value']);
+          }
+          break;
+      }
+      return;
+
+    case 'update':
+      $node_field = $node->$field['field_name'];
+      // Delete and insert, rather than update, in case a field was added.
+      switch($field['type']) {
+        case 'number_integer':
+          db_query("DELETE FROM {node_field_int_data} WHERE vid = %d AND field_name = '%s'", $node->vid, $field['field_name']);
+          if ($field['multiple']) {
+            foreach ($node_field as $delta => $item) {
+              db_query("INSERT INTO {node_field_int_data} (vid, field_name, delta, field_int) VALUES (%d, '%s', %d, %d)", $node->vid, $field['field_name'], $delta, $item['value']);
+            }
+          }
+          else {
+            db_query("INSERT INTO {node_field_int_data} (vid, field_name, field_int) VALUES (%d, '%s', %d)", $node->vid, $field['field_name'], $node_field['value']);
+          }
+          break;
+        case 'number_decimal':
+          db_query("DELETE FROM {node_field_float_data} WHERE vid = %d AND field_name = '%s'", $node->vid, $field['field_name']);
+          if ($field['multiple']) {
+            foreach ($node_field as $delta => $item) {
+              db_query("INSERT INTO {node_field_float_data} (vid, field_name, delta, field_float) VALUES (%d, '%s', %d, %d)", $node->vid, $field['field_name'], $delta, $item['value']);
+            }
+          }
+          else {
+            db_query("INSERT INTO {node_field_float_data} (vid, field_name, field_float) VALUES (%d, '%s', %d)", $node->vid, $field['field_name'], $node_field['value']);
+          }
+          break;
+      }
+      return;
+
+    case 'delete':
+      switch($field['type']) {
+        case 'number_integer':
+          db_query("DELETE FROM {node_field_int_data} WHERE vid = %d AND field_name = '%s'", $node->vid, $field['field_name']);
+          break;
+        case 'number_decimal':
+          db_query("DELETE FROM {node_field_float_data} WHERE vid = %d AND field_name = '%s'", $node->vid, $field['field_name']);
+          break;
+      }
+      return;
+  }
+}
+
+/**
+ * Implementation of hook_field_query().
+ */
+function number_field_query($field, $op, $value) {
+  $query_additions = array();
+
+  $table_name = ($field['type'] == 'number_integer' ? 'node_field_int_data' : 'node_field_float_data');
+  $column_name = ($field['type'] == 'number_integer' ? 'field_int' : 'field_float');
+
+  switch ($op) {
+    case 'is':
+      $query_additions['tables'] = array('%table' => $table_name);
+      $query_additions['where'] = "%table.". $column_name ." = %d";
+      $query_additions['data'] = array($value);
+      break;
+
+    case 'over':
+      $query_additions['tables'] = array('%table' => $table_name);
+      $query_additions['where'] = "%table.". $column_name ." > %d";
+      $query_additions['data'] = array($value);
+      break;
+
+    case 'under':
+      $query_additions['tables'] = array('%table' => $table_name);
+      $query_additions['where'] = "%table.". $column_name ." < %d";
+      $query_additions['data'] = array($value);
+      break;
+  }
+
+  return $query_additions;
+}
+
+?>
\ No newline at end of file
diff --git a/text.module b/text.module
new file mode 100644
index 00000000..82cc671d
--- /dev/null
+++ b/text.module
@@ -0,0 +1,307 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Defines standard simple field types.
+ */
+
+/**
+ * Implementation of hook_help().
+ */
+function text_help($section) {
+  switch ($section) {
+    case 'admin/modules#description':
+      return t('Defines simple text field types.');
+  }
+}
+
+/**
+ * Implementation of hook_field_info().
+ */
+function text_field_info() {
+  return array(
+    'text_shorttext' => array('label' => 'Short Text'),
+    'text_longtext' => array('label' => 'Long Text'),
+  );
+}
+
+/**
+ * Implementation of hook_field_settings().
+ */
+function text_field_settings($op, $field, $scope) {
+  switch ($op) {
+    case 'form':
+      $form = array();
+      switch ($scope) {
+        case 'instance':
+          $form['rows'] = array(
+            '#type' => 'textfield',
+            '#title' => t('Rows'),
+            '#default_value' => $field['rows'] ? $field['rows'] : 1,
+            '#required' => TRUE,
+          );
+          break;
+
+        case 'global':
+          $options = array(0 => t('Plain text'), 1 => t('Filtered text (user selects input format)'));
+          $form['text_processing'] = array(
+            '#type' => 'radios',
+            '#title' => t('Text processing'),
+            '#default_value' => $field['text_processing'] ? $field['text_processing'] : 0,
+            '#options' => $options,
+          );
+          break;
+      }
+      return $form;
+    
+    case 'validate':
+      switch ($scope) {
+        case 'instance':
+          if (!is_numeric($field['rows']) || intval($field['rows']) != $field['rows'] || $field['rows'] <= 0) {
+            form_set_error('rows', t('"Rows" must be a positive integer.'));
+          }
+          break;
+      }
+      break;
+
+    case 'save':
+      switch ($scope) {
+        case 'instance':
+          return array('rows');
+        case 'global':
+          return array('text_processing');
+      }
+      break;
+  }
+}
+
+/**
+ * Implementation of hook_field().
+ */
+function text_field($op, $node, $field, $a2, $a3, $a4) {
+  switch ($op) {
+    case 'load':
+      switch($field['type']) {
+        case 'text_shorttext':
+          $result = db_query("SELECT field_shorttext, format FROM {node_field_shorttext_data} WHERE vid = %d AND field_name = '%s' ORDER BY delta", $node->vid, $field['field_name']);
+          if ($field['multiple']) {
+            $values = array();
+            while ($value = db_fetch_object($result)) {
+              $values[] = array('value' => $value->field_shorttext, 'format' => $value->format);
+            }
+            $additions = array($field['field_name'] => $values);
+          }
+          else {
+            $value = db_fetch_object($result);
+            $additions = array($field['field_name'] => array('value' => $value->field_shorttext, 'format' => $value->format));
+          }
+          break;
+        case 'text_longtext':
+          $result = db_query("SELECT field_longtext, format FROM {node_field_longtext_data} WHERE vid = %d AND field_name = '%s' ORDER BY delta", $node->vid, $field['field_name']);
+          if ($field['multiple']) {
+            $values = array();
+            while ($value = db_fetch_object($result)) {
+              $values[] = array('value' => $value->field_longtext, 'format' => $value->format);
+            }
+            $additions = array($field['field_name'] => $values);
+          }
+          else {
+            $value = db_fetch_object($result);
+            $additions = array($field['field_name'] => array('value' => $value->field_longtext, 'format' => $value->format));
+          }
+          break;
+      }
+      return $additions;
+
+    case 'view':
+      $output = '';
+      $node_field = $node->$field['field_name'];
+      if ($field['multiple']) {
+        foreach ($node_field as $delta => $item) {
+          if ($field['text_processing']) {
+            $node_field[$delta]['view'] = check_markup($item['value'], $item['format'], isset($node->in_preview) ? $node->in_preview : FALSE);
+          }
+          else {
+            $node_field[$delta]['view'] = check_plain($item['value']);
+          }
+        }
+      }
+      else {
+        if ($field['text_processing']) {
+          $node_field['view'] = check_markup($node_field['value'], $node_field['format'], isset($node->in_preview) ? $node->in_preview : FALSE);
+        }
+        else {
+          $node_field['view'] = check_plain($node_field['value']);
+        }
+      }
+      $node->$field['field_name'] = $node_field;
+      if ($field['multiple']) {
+        $output = '';
+        foreach ($node_field as $delta => $item) {
+          $output .= '<div class="'. $field['field_name'] .'">'. $item['view'] .'</div>';
+        }
+        return $output;
+      }
+      else {
+        return '<div class="'. $field['field_name'] .'">'. $node_field['view'] .'</div>';
+      }
+
+    case 'form':
+      $form = array();
+      $node_field = $node->$field['field_name'];
+
+      $form[$field['field_name']] = array('#tree' => TRUE);
+
+      if ($field['multiple']) {
+        foreach (range(0, 2) as $delta) {
+          if ($field['rows'] == 1) {
+            $form[$field['field_name']][$delta]['value'] = array(
+              '#type' => 'textfield',
+              '#title' => t($field['label']),
+              '#default_value' => $node_field[$delta]['value'],
+              '#required' => ($delta == 0) ? $field['required'] : FALSE,
+            );
+          }
+          else {
+            $form[$field['field_name']][$delta]['value'] = array(
+              '#type' => 'textarea',
+              '#title' => t($field['label']),
+              '#default_value' => $node_field[$delta]['value'],
+              '#required' => ($delta == 0) ? $field['required'] : FALSE,
+              '#rows' => $field['rows'],
+            );
+          }
+          if ($field['text_processing']) {
+            $form[$field['field_name']][$delta] = array_merge($form[$field['field_name']][$delta], filter_form($node_field[$delta]['format']));
+          }
+        }
+      }
+      else {
+        if ($field['rows'] == 1) {
+          $form[$field['field_name']]['value'] = array(
+            '#type' => 'textfield',
+            '#title' => t($field['label']),
+            '#default_value' => $node_field['value'],
+            '#required' => $field['required'],
+          );
+        }
+        else {
+          $form[$field['field_name']]['value'] = array(
+            '#type' => 'textarea',
+            '#title' => t($field['label']),
+            '#default_value' => $node_field['value'],
+            '#required' => $field['required'],
+            '#rows' => $field['rows'],
+          );
+        }
+        if ($field['text_processing']) {
+          $form[$field['field_name']] = array_merge($form[$field['field_name']], filter_form($node_field['format']));
+        }
+      }
+      return $form;
+
+    case 'validate':
+      return;
+
+    case 'insert':
+      $node_field = $node->$field['field_name'];
+      switch($field['type']) {
+        case 'text_shorttext':
+          if ($field['multiple']) {
+            foreach ($node_field as $delta => $item) {
+              db_query("INSERT INTO {node_field_shorttext_data} (vid, field_name, delta, field_shorttext, format) VALUES (%d, '%s', %d, '%s', %d)", $node->vid, $field['field_name'], $delta, $item['value'], $item['format']);
+            }
+          }
+          else {
+            db_query("INSERT INTO {node_field_shorttext_data} (vid, field_name, field_shorttext, format) VALUES (%d, '%s', '%s', %d)", $node->vid, $field['field_name'], $node_field['value'], $node_field['format']);
+          }
+          break;
+        case 'text_longtext':
+          if ($field['multiple']) {
+            foreach ($node_field as $delta => $item) {
+              db_query("INSERT INTO {node_field_longtext_data} (vid, field_name, delta, field_longtext, format) VALUES (%d, '%s', %d, '%s', %d)", $node->vid, $field['field_name'], $delta, $item['value'], $item['format']);
+            }
+          }
+          else {
+            db_query("INSERT INTO {node_field_longtext_data} (vid, field_name, field_longtext, format) VALUES (%d, '%s', '%s', %d)", $node->vid, $field['field_name'], $node_field['value'], $node_field['format']);
+          }
+          break;
+      }
+      return;
+
+    case 'update':
+      $node_field = $node->$field['field_name'];
+      // Delete and insert, rather than update, in case a field was added.
+      switch($field['type']) {
+        case 'text_shorttext':
+          db_query("DELETE FROM {node_field_shorttext_data} WHERE vid = %d AND field_name = '%s'", $node->vid, $field['field_name']);
+          if ($field['multiple']) {
+            foreach ($node_field as $delta => $item) {
+              db_query("INSERT INTO {node_field_shorttext_data} (vid, field_name, delta, field_shorttext, format) VALUES (%d, '%s', %d, '%s', %d)", $node->vid, $field['field_name'], $delta, $item['value'], $item['format']);
+            }
+          }
+          else {
+            db_query("INSERT INTO {node_field_shorttext_data} (vid, field_name, field_shorttext, format) VALUES (%d, '%s', '%s', %d)", $node->vid, $field['field_name'], $node_field['value'], $node_field['format']);
+          }
+          break;
+        case 'text_longtext':
+          db_query("DELETE FROM {node_field_longtext_data} WHERE vid = %d AND field_name = '%s'", $node->vid, $field['field_name']);
+          if ($field['multiple']) {
+            foreach ($node_field as $delta => $item) {
+              db_query("INSERT INTO {node_field_longtext_data} (vid, field_name, delta, field_longtext, format) VALUES (%d, '%s', %d, '%s', %d)", $node->vid, $field['field_name'], $delta, $item['value'], $item['format']);
+            }
+          }
+          else {
+            db_query("INSERT INTO {node_field_longtext_data} (vid, field_name, field_longtext, format) VALUES (%d, '%s', '%s', %d)", $node->vid, $field['field_name'], $node_field['value'], $node_field['format']);
+          }
+          break;
+      }
+      return;
+
+    case 'delete':
+      switch($field['type']) {
+        case 'field_shorttext':
+          db_query("DELETE FROM {node_field_shorttext_data} WHERE vid = %d AND field_name = '%s'", $node->vid, $field['field_name']);
+          break;
+        case 'field_longtext':
+          db_query("DELETE FROM {node_field_longtext_data} WHERE vid = %d AND field_name = '%s'", $node->vid, $field['field_name']);
+          break;
+      }
+      return;
+  }
+}
+
+/**
+ * Implementation of hook_field_query().
+ */
+function text_field_query($field, $op, $value) {
+  $query_additions = array();
+
+  $table_name = ($field['type'] == 'field_shorttext' ? 'node_field_shorttext_data' : 'node_field_longtext_data');
+  $column_name = ($field['type'] == 'field_shorttext' ? 'field_shorttext' : 'field_longtext');
+
+  switch ($op) {
+    case 'is':
+      $query_additions['tables'] = array('%table' => $table_name);
+      $query_additions['where'] = "%table.". $column_name ." = '%s'";
+      $query_additions['data'] = array($value);
+      break;
+
+    case 'contains':
+      $query_additions['tables'] = array('%table' => $table_name);
+      $query_additions['where'] = "%table.". $column_name ." LIKE '%%%s%%'";
+      $query_additions['data'] = array($value);
+      break;
+
+    case 'like':
+      $query_additions['tables'] = array('%table' => $table_name);
+      $query_additions['where'] = "%table.". $column_name ." LIKE '%s'";
+      $query_additions['data'] = array($value);
+      break;
+  }
+
+  return $query_additions;
+}
+
+?>
\ No newline at end of file
-- 
GitLab