You are here

Drupal 7 - A Simple Content Type: Text fields and areas

This post builds upon a previous post: Drupal 7 - A Simple Content Type

Text fields and areas are one of the main ways to gather data from users whether they are filling out your site contact form or submitting an article to your site. Our Simple Content Type already contains a text field, the title, and a text area, the body, although they are not declared that way. The title field is the only default field for nodes and we will use one in this example but we will not include a body in this version of Simple Content Type as we already know how to add a body to our content types and having the body field will just clutter up the display. Let's get started by uninstalling any previous copies of the Simple Content Type module. Next, let's add three fields: one text field and two text areas, one with format filters and one without. Here is our updated hook_install() function:


function simple_content_type_install() {
  // create the simple content type
  node_types_rebuild();
  $types = node_type_get_types();
  
  // create all the fields we are adding to our content type
  foreach (_simple_content_type_installed_fields() as $field) {
    field_create_field($field);
  }
  
  // create all the instance for our fields
  foreach (_simple_content_type_installed_instances() as $instance) {
    $instance['entity_type'] = 'node';
    $instance['bundle'] = 'simple_content_type';
    field_create_instance($instance);
  }
  
  // disable comments for this content type
  variable_set('comment_simple_content_type', COMMENT_NODE_CLOSED);
}

Just like in other examples we use two foreach statements coupled with functions that return associative arrays to make the task of adding fields to our content type easy. We could just stuff the settings into the install function but using functions for this task makes the code more readable. We next need to modify the uninstall hook to delete any fields we created for our content type. Here is our hook_uninstall() function:


function simple_content_type_uninstall() {
  // gather all the content while the module was enabled
  $sql = 'SELECT nid FROM {node} n WHERE n.type = :type';
  $result = db_query($sql, array(':type' => 'simple_content_type'));
  $nids = array();
  foreach ($result as $row) {
    $nids[] = $row->nid;
  }
  
  // delete all the nodes at once
  node_delete_multiple($nids);

  // delete all the fields defined by this module
  foreach (array_keys(_simple_content_type_installed_fields()) as $field) {
    field_delete_field($field);
  }

  // delete any remaining field instances attached to this content type
  $instances = field_info_instances('node', 'simple_content_type');
  foreach ($instances as $instance_name => $instance) {
    field_delete_instance($instance);
  }
  
  // delete our content type
  node_type_delete('simple_content_type');
  
  // purge all field information
  field_purge_batch(1000);
}

Both of the functions we are using in the above hooks reside in a file called 'simple_content_type_functions.inc'. This file will hold all the non-hook functions we code for use in our hooks. In order to use the functions in this file we need to add the new functions file to the .install file:


require_once('simple_content_type_functions.inc');

We could also add this file include to the .module file to share functions, but in our example we have no need for it there. Our file, simple_content_type_functions.inc, has two functions:


function _simple_content_type_installed_fields()  {
  // textfield
  $fields['simple_content_type_textfield'] = array(
    'field_name' => 'simple_content_type_textfield',
    'label' => t('A Textfield'),
    'type' => 'text',
    'module' => 'text',
  );
  // text area without filters
  $fields['simple_content_type_textarea'] = array(
    'field_name' => 'simple_content_type_textarea',
    'label' => t('A Textarea'),
    'type' => 'text_long',
    'module' => 'text',
    'translatable' => '1',
    'foreign keys' => array(
      'format' => array(
        'columns' => array(
          'format' => 'format',
        ),
        'table' => 'filter_format',
      ),
    ),
    'indexes' => array(
      'format' => array(
        0 => 'format',
      ),
    ),
  );
  // text area with filters
  $fields['simple_content_type_txtarea_fltr'] = array(
    'field_name' => 'simple_content_type_txtarea_fltr',
    'label' => t('A Textarea with format filters'),
    'type' => 'text_long',
    'module' => 'text',
    'translatable' => '1',
    'foreign keys' => array(
      'format' => array(
        'columns' => array(
          'format' => 'format',
        ),
        'table' => 'filter_format',
      ),
    ),
    'indexes' => array(
      'format' => array(
        0 => 'format',
      ),
    ),
  );
  
  return $fields;
}

function _simple_content_type_installed_instances()  {
  // textfield
  $instances['simple_content_type_textfield'] = array(
    'field_name' => 'simple_content_type_textfield',
    'type' => 'text',
    'label' => t('A Textfield'),
    'widget' => array(
      'type' => 'text_textfield',
      'weight' => '-1',
	  'settings' => array(
                'size' => '20',
		'max_length' => '100',
      ),
    ),
    'display' => array(
      'default' => array(
        'label' => 'inline',
        'settings' => array(),
        'type' => 'text_default',
        'weight' => -1,
      ),
      'teaser' => array(
        'label' => 'above',
        'settings' => array(),
        'type' => 'hidden',
        'weight' => -1,
      ),
    ),
  );
  // textarea without filters
  $instances['simple_content_type_textarea'] = array(
    'field_name' => 'simple_content_type_textarea',
    'type' => 'text_long',
    'label' => t('A Textarea'),
    'widget' => array(
      'settings' => array(
        'rows' => '5',
      ),
      'type' => 'text_textarea',
      'weight' => 0,
    ),
    'display' => array(
      'default' => array(
        'label' => 'above',
        'settings' => array(),
        'type' => 'text_default',
        'weight' => 0,
      ),
      'teaser' => array(
        'label' => 'above',
        'settings' => array(),
        'type' => 'hidden',
        'weight' => 0,
      ),
    ),
    'required' => 0,
    'settings' => array(
      'text_processing' => '0',
      'user_register_form' => FALSE,
    ),
  );
  // textarea with filters
  $instances['simple_content_type_txtarea_fltr'] = array(
    'field_name' => 'simple_content_type_txtarea_fltr',
    'type' => 'text_long',
    'label' => t('A Textarea with format filters'),
    'widget' => array(
      'settings' => array(
        'rows' => '5',
      ),
      'type' => 'text_textarea',
      'weight' => 1,
    ),
    'display' => array(
      'default' => array(
        'label' => 'above',
        'settings' => array(),
        'type' => 'text_default',
        'weight' => 1,
      ),
      'teaser' => array(
        'label' => 'above',
        'settings' => array(),
        'type' => 'hidden',
        'weight' => 1,
      ),
    ),
    'required' => 0,
    'settings' => array(
      'text_processing' => '1',
      'user_register_form' => FALSE,
    ),
  );
  
  return $instances;
}

We start by defining a text field with a size of 20 and a maximum length of 100 characters. By defining these values when creating the fields we tell Drupal to place these restrictions on all instances of that field when validating any data submitted through them. Next we set up two almost identical text areas. Text areas are similar to text fields in that you can define the size of the area to present but instead of using 'size' and 'maxlength' we need to use 'rows' and 'cols'. Our text areas are the same size but do have one crucial difference which dramatically alters there functionality: text_processing. By setting 'text_processing' to 0 in the first text area we disallow format filters from being used on the text in the area. Setting 'text_processing' to 1 allows format filters to be used which can provide a multitude of options to the user. Install and test and you should see something like below:

Add a new Simple Content Type

Download the source for this example.

Tags: