Saturday, May 21, 2011

Setup a new content type on install and add fields- Drupal 7 field API

Adding customs Fields on Drupal module installation:


At the moment we are building a Drupal 7 site which requires everything to be enabled
on install via modules / custom profiles. Below is a content type with some extra fields
added using Field API so you can see how they are added. This should go in the module
*.install file. We go through the standard process of setting up a content type, and call
installed_fields and installed_instances functions. You might want to rename it from
‘article’ to something else, from what I remember on the standard install profile, Drupal 7
already creates a content type called article.
drupal-field-api
Screenshot


function article_install() {
  // get the translation function relevant to our current localisation
  $t = get_t();
  // define the content type as an array (same as in hook_node_info())
  $article = array(
    'type' => 'article',
    'name' => $t('Article'),
    'base' => 'node_content',
    'description' => $t('Content type to handle articles.'),
    'body_label' => $t('Article Description'),
    'promote' => 0,
    'status' => 1,
    'comment' => 0,
  );
 
  // set default values for anything not explicitly defined in the above array
 
  $content_type = node_type_set_defaults($article);
 
  // add the body field to the content type
  node_add_body_field($content_type, 'Body');
 
  // create the content type
 
  node_type_save($content_type);
 
  variable_set('node_options_article', array('status'));
  // hide comments for this node. http://api.drupal.org/api/drupal/modules--comment--comment.module/7
  variable_set('comment_article', 'COMMENT_NODE_HIDDEN');
 
  // Hide date and author information
 
  variable_set('node_submitted_article', FALSE);
 
  // Create all the fields we are adding to our content type.
  // http://api.drupal.org/api/function/field_create_field/7
  foreach (_article_installed_fields() as $field) {
    field_create_field($field);
  }
 
  // Create all the instances for our fields.
 
  // http://api.drupal.org/api/function/field_create_instance/7
  foreach (_article_installed_instances() as $instance) {
    $instance['entity_type'] = 'node';
    $instance['bundle'] = 'article';
    field_create_instance($instance);
  }
 
  // adjust the weight so it's called after a dependant module called 'categories'
 
  $weight = db_query("SELECT weight FROM {system} WHERE name = :name", array(':name' => 'categories'))->fetchField();
  db_update('system')->fields(array(
    'weight' => $weight + 1,
  ))
  ->condition('name', 'article')
  ->execute();
}
 
 
 
function _article_installed_fields() {
  $t = get_t();
  $fields = array(
    // text field
    'article_source' => array(
      'field_name'   => 'article_source',
      'label'        => $t('Artcile Source'),
      'cardinality'  => 1,
      'type'         => 'text',
      'settings'     => array(
        'max_length'  => 1000,
      ),
    ),
    // taxonomy term reference field, referencing a vocabulary called 'authors'
 
    'article_author' => array(
      'field_name' => 'article_author',
      'type' => 'taxonomy_term_reference',
      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
      'settings' => array(
        'allowed_values' => array(
          array(
            'vocabulary' => 'authors',
            'parent' => 0,
          ),
        ),
      ),
    ),
      // node refererence auto complete field (see the instance), referencing a content-type called 'work'
 
    'article_work_ref' => array(
      'field_name'  => 'article_work_ref',
      'label'       => $t('Work refrerence'),
      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
      'type'        => 'node_reference',
      'settings'    => array(
        'referenceable_types'  => array('work'),
      ),
    ),
    // a text (textarea) field
 
    'article_pullquote' => array(
      'field_name'   => 'article_pullquote',
      'label'        => $t('Pull Quote'),
      'cardinality'  => 1,
      'type'         => 'text',
      'settings'     => array(
        'max_length'  => 1000,
      ),
    ),
    // image field
 
    'article_image' => array(
      'field_name' => 'article_image',
      'label' => $t('Image'),
      'cardinality' => 1,
      'type' => 'image',
      'settings' => array(
        'default_image' => 0,
        'uri_scheme' => 'public',
      ),
    ),
    // date field (date module required)
 
    'article_date' => array(
      'field_name'   => 'article_date',
      'label'        => $t('Date'),
      'cardinality'  => 1,
      'type'         => 'date',
    ),
  );
  return $fields;
}
 
 
 
function _article_installed_instances() {
  $t = get_t();
  $instances = array(
    // instance of the text field above
    'article_source' => array(
      'field_name'  => 'article_source',
      'label'       => $t('Article Source'),
      'cardinality' => 1,
      'widget'      => array(
        'type'       => 'text_textfield',
        'settings'   => array('size' => 60),
      ),
    ),
    // instance of the taxonomy term reference field above
 
    'article_author' => array(
      'field_name' => 'article_author',
      'entity_type' => 'node',
      'label' => $t('Author'),
      'bundle' => 'article',
      'required' => FALSE,
      'widget' => array(
        'type' => 'options_select',
      ),
    ),
      // instance of the node reference 'work' auto complete field above
 
    'article_work_ref' => array(
      'field_name'  => 'article_work_ref',
      'label'       => $t('Work refrerence'),
      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
      'widget'      => array(
        'type'          => 'node_reference_autocomplete',
      ),
    ),
    // instance of the textarea field above
 
    'article_pullquote' => array(
      'field_name'  => 'article_pullquote',
      'label'       => $t('Pull Quote'),
      'cardinality' => 1,
      'widget'      => array(
        'type'       => 'text_textarea',
        'settings'   => array('rows' => 5),
      ),
    ),
    // instance of the image field above
 
    'article_image' => array(
      'field_name' => 'article_image',
      'label' => $t('Image'),
      'cardinality' => 1,
      'type' => 'article_image',
      'settings' => array(
        'alt_field' => 1,
        'file_directory' => 'image',
        'file_extensions' => 'png gif jpg jpeg',
        'max_filesize' => '',
        'max_resolution' => '',
        'min_resolution' => '',
        'title_field' => 1,
        'user_register_form' => FALSE,
      ),
      'widget' => array(
        'settings' => array(
          'preview_image_style' => 'thumbnail',
          'progress_indicator' => 'throbber',
        ),
      ),
      'display' => array(
        'default' => array(
          'label' => 'hidden',
          'type' => 'image',
          'settings' => array('image_style' => 'bfi_common_features_image', 'image_link' => ''),
          'weight' => -1,
        ),
        'teaser' => array(
          'label' => 'hidden',
          'type' => 'image',
          'settings' => array('image_style' => 'thumbnail', 'image_link' => 'content'),
          'weight' => -1,
        ),
      ),
    ),
    // instance of the date field above
 
    'article_date' => array(
      'field_name'  => 'article_date',
      'label'       => $t('Date'),
      'cardinality' => 1,
      'widget'      => array(
        'type'       => 'date_select',
        'settings'   => array(
          'input_format' => date_default_format('date_select'),
          'increment' => 1,
          'year_range' => '-3:+3',
        ),
        'behaviors' => array(
          'multiple values' => FIELD_BEHAVIOR_CUSTOM,
          'default value' => FIELD_BEHAVIOR_CUSTOM,
        ),
      ),
    ),
  );
  return $instances;
}
 
 
 
 
function article_uninstall() {
  // Gather all the example content that might have been created while this
  // module was enabled.  Simple selects still use db_query().
  // http://api.drupal.org/api/function/db_query/7
  $sql = 'SELECT nid FROM {node} n WHERE n.type = :type';
  $result = db_query($sql, array(':type' => 'article'));
  $nids = array();
  foreach ($result as $row) {
    $nids[] = $row->nid;
  }
 
  // Delete all the nodes at once
 
  // http://api.drupal.org/api/function/node_delete_multiple/7
  node_delete_multiple($nids);
 
 
  // Loop over each of the fields defined by this module and delete
  // all instances of the field, their data, and the field itself.
  // http://api.drupal.org/api/function/field_delete_field/7
  foreach (array_keys(_article_installed_fields()) as $field) {
    field_delete_field($field);
  }
 
  // Delete our content type
 
  // http://api.drupal.org/api/function/node_type_delete/7
  node_type_delete('article');
 
  // Purge all field information
  // http://api.drupal.org/api/function/field_purge_batch/7
  field_purge_batch(1000);
}

7 comments:

  1. Hi there,

    Thanks for the fantastic tutorial. Please help me out here. I am trying to create a user_reference fieid but the autocomplete doesnt seem to be working. Please tell me where I am going wrong.

    Here are my field and instance settings :

    field :

    'vocabulary_authors' => array(
    'field_name' => 'vocabulary_authors',
    'type' => 'user_reference',
    'settings' => array(
    'referenceable_roles' => array('2','3'),
    'referenceable_status' => array('1'),
    ),
    'default_widget' => 'user_reference_autocomplete',
    'default_formatter' => 'user_reference_default',
    'cardinality' => FIELD_CARDINALITY_UNLIMITED,
    ),


    instance :

    'vocabulary_authors' => array(
    'field_name' => 'vocabulary_authors',
    'label' => $t(' Authors'),
    'bundle' => 'vocabulary',
    'entity_type' => 'node',
    'description' => '',
    'required' => FALSE,
    'widget' => array(
    'type' => 'user_reference_autocomplete',
    'settings' => array(
    'autocomplete_match' => 'starts_with',
    ),
    ),


    Please help me. Probably I am missing out on some field setting ? specifying max_length doesnt help either.

    ReplyDelete
  2. Which version of Drupal you are using?

    ReplyDelete
  3. So clear! I'd like to find it in Drupal's docs

    ReplyDelete
  4. Hi, did you have any luck with finding the missing setting ?

    Sorry for disturbing :)

    ReplyDelete
  5. fixed, refer :
    http://drupal.org/node/1165740#comment-4575118

    ReplyDelete
  6. Hiii, this code works smoothly in drupal 7 by referring http://drupal.org/node/1165740#comment-4575118 but as i update my version to 8 so do this work on that too?

    ReplyDelete