Drupal 7's Field API is a very handy system of functions that allow easy creation and manipulation of Drupal fields. Taking much from the popular Drupal 6 module CCK, the Field API allows a developer to easily programmatcially create and manage fields. All field attributes that exist in the UI can be added, removed, or altered through various Field API functions. The first example I will show will simply create a textfield. We will start with just the field, then add on to it.

$field_name = 'field_alias';
 
// Create the field.
$field = array(
  'field_name' => $field_name,
  'type' => 'text',
  'settings' => array(
    'max_length' => 64,
  ),
);
field_create_field($field);

We start by selecting a field name. You want to prefix the name with "field_" because that is how Drupal core does it. We then set the attributes to an array called "$field". In this example we chose to set "field_name", "type", and "settings". We are going to use a text field so the type should be "text". You can get a list of available types by checking out hook_field_info(). We want the field to have a max length of 64 characters, so we set that in the field settings.

So now we have a field. We should now attach it to an entity and a bundle. In this case let's attach it to an article node. Our new code will look like...

$field_name = 'field_alias';
 
// Create the field.
$field = array(
  'field_name' => $field_name,
  'type' => 'text',
  'settings' => array(
    'max_length' => 64,
  ),
);
field_create_field($field);
 
// Create the instance.
$instance = array(
  'field_name' => $field_name,
  'entity_type' => 'node',
  'bundle' => 'article',
  'label' => 'Alias',
  'description' => 'The article alias.',
  'required' => TRUE,
);
 
field_create_instance($instance);

In the code above, we have attached the field to an instance. Now when you pull up an article, the new field will be ready for use. Here's a quick overview of the attributes for the instance array.

  • field_name - The name of the field. Should match what you added to the field array.
  • entity_type - The type of entity where this field can be displayed. In this case we chose node, but any entity will do. You can also use mutlple entities.
  • bundle - The bundle associated with the entity. In this case we chose article. A user entity would use the bundle of user.
  • lable - The name that will be shown to users.
  • description - A description of the field when editing the entity.
  • required - Determines if the field should be required.

Finally lets place this in a function so it can be executed. In this example lets place it in an update hook.

/**
 * Update hook to add a field to a node.
 */
function my_module_update_7000() {
  $field_name = 'field_alias';
 
  // Make sure the field doesn't already exist.
  if (!field_info_field($field_name)) {
      // Create the field.
      $field = array(
        'field_name' => $field_name,
        'type' => 'text',
        'settings' => array(
          'max_length' => 64,
        ),
      );
      field_create_field($field);
 
      // Create the instance.
      $instance = array(
        'field_name' => $field_name,
        'entity_type' => 'node',
        'bundle' => 'article',
        'label' => 'Alias',
        'description' => 'The article alias.',
        'required' => TRUE,
      );
 
      field_create_instance($instance);
      watchdog('my_module', t('!field_name was added successfully.', array('!field_name' => $field_name)));
  }
  else {
    watchdog('my_module', t('!field_name already exists.', array('!field_name' => $field_name)));
  }
}

Now when we run the database update script it will add the field to the article entity. We also added a check to make sure the field didn't already exist. Lastly we added a few watchdog functions to log the status of the field.

Easy enough right? Now lets create an image field. This image field will use quite a few more settings. We are going to restrict file size, type, and resolution. We are also going to add the image to a lightbox and image styles. If you are not familiar with lightbox, check out the curtiousy of the Lightbox2 Module.

Lets get started. We are going to recreate the basics again, but this time with an image. First lets take a look at how to create the field. This time it will be nice and simple.

$field_name = 'field_article_image';
 
// Create the field.
$field = array(
  'field_name' => $field_name,
  'type' => 'image',
);
field_create_field($field);

Now lets set up the instance. This is where the magic will happen. We are going to add the basics as we did in the previous example. We are also going to add settings and display. After all, it is an image.

// Create the instance.
$instance = array(
  'field_name' => $field_name,
  'entity_type' => 'node',
  'bundle' => 'article',
  'label' => 'Article Image',
  'description' => 'An image for the article.',
  'required' => TRUE,
  'settings' => array(
    'file_extensions' => 'png jpg jpeg',
    'file_directory' => '',
    'max_filesize' => '20 MB',
    'alt_field' => 1,
    'title_field' => 1,
    'max_resolution' => '300x200',
    'min_resolution' => '200x125',
    'default_image' => 0,
  ),
  'display' => array(
    'default' => array(
      'label' => 'hidden',
      'type' => 'lightbox2__lightbox__large__original',
      'weight' => 0,
      'settings' => array(),
      'module' => 'lightbox2',
    ),
    'full' => array(
      'label' => 'hidden',
      'type' => 'imagefield__lightbox2__large__original',
      'weight' => 0,
    ),
    'teaser' => array(
      'label' => 'hidden',
      'type' => 'image',
      'weight' => 0,
      'settings' => array(),
      'module' => 'image',
    ),
  )
);
 
field_create_instance($instance);

Now that is a big instance. Lets go through the new keys.

    Settings
  • file_extensions - The file extensions that will be accepted.
  • file_directory - The directory that the images will be served from. By default this is your public files directory.
  • max_filesize - The maximum size a file can be. May us values such as 1 GB, 200 KB, etc.
  • alt_field - Boolean value to expose the alt attribute.
  • title_field - Boolean value to expose the title attribute.
  • max_resolution - The maximum resolution a picture can be, in pixels.
  • min_resolution - The minimum resolution a picutre ca be, in pixels.
  • default_image - The default image that will be used if no image is selected.

Nothing too difficult there. They are all basic attributes that should be considered for any image on the site. Next, lets take a look at the display settings.

    Display
  • Default - The default display that is shown to users.
    • label - Whether or not the label should be shown to users. In this case we want to hide it. After all, a picture is worth a thousand words, why add a few more?
    • type - The style in which the image should be displayed.
    • weight - Positions the field for display. Lower floats, higher sinks.
    • settings - Any additional settings in which you want to apply to the lightbox.
    • module - The module that controls the type.
  • full - The full display of the node.
  • teaser - When the node is shown, but not on the node page!

Now lets place this in an update hook and be done with it!.

/**
 * Update hook to add an image field to a node.
 */
function test_update_7001() {
  $field_name = 'field_article_image';
 
  // Make sure the field doesn't already exist.
  if (!field_info_field($field_name)) {
      // Create the field.
      $field = array(
        'field_name' => $field_name,
        'type' => 'image',
      );
      field_create_field($field);
 
      // Create the instance.
      $instance = array(
        'field_name' => $field_name,
        'entity_type' => 'node',
        'bundle' => 'article',
        'label' => 'Article Image',
        'description' => 'An image for the article.',
        'required' => TRUE,
        'settings' => array(
          'file_extensions' => 'png jpg jpeg',
          'file_directory' => '',
          'max_filesize' => '20 MB',
          'alt_field' => 1,
          'title_field' => 1,
          'max_resolution' => '300x200',
          'min_resolution' => '200x125',
          'default_image' => 0,
        ),
        'display' => array(
          'default' => array(
            'label' => 'hidden',
            'type' => 'lightbox2__lightbox__large__original',
            'weight' => 0,
            'settings' => array(),
            'module' => 'lightbox2',
          ),
          'full' => array(
            'label' => 'hidden',
            'type' => 'imagefield__lightbox2__large__original',
            'weight' => 0,
          ),
          'teaser' => array(
            'label' => 'hidden',
            'type' => 'image',
            'weight' => 0,
            'settings' => array(),
            'module' => 'image',
          ),
        )
      );
 
      field_create_instance($instance);
      watchdog('my_module', t('!field_name was added successfully.', array('!field_name' => $field_name)));
  }
  else {
    watchdog('my_module', t('!field_name already exists.', array('!field_name' => $field_name)));
  }
}

So all in all, fields are pretty easy to create in Drupal.

At this point you may be asking yourself "Why not just use the UI?". Well the simple answer is that these changes can be applied programmatically. This means that if you have to push this code to a development site, then the production site, you are recreating the same field through the UI 2 additional times. With an update hook, you just run update.php (drush updatedb) and you are done. This can save a lot of pain for bigger database updates, such as creating a node and adding ten fields to it.