Correct way to use Drupal 7 Entities and Field API

Martin Petts picture Martin Petts · Jan 15, 2011 · Viewed 11.7k times · Source

I'm trying to use Drupal 7's entities and field API to correctly build a new module. What I have been unable to understand from the documentation is the correct way to use the new API to create a 'content type' (not a node type) with a number of set fields, such as Body.

I'm trying to set up the entity using hook_entity_info, then I believe I need to add the body field using field_create_instance, but I can't seem to get it to work.

In mycontenttype.module:

/**
 * Implements hook_entity_info().
 */
function mycontenttype_entity_info() {
  $return = array(
    'mycontenttype' => array(
      'label' => t('My Content Type'),
      'controller class' => 'MyContentTypeEntityController',
      'base table' => 'content_type',
      'uri callback' => 'content_type_uri',
      'entity keys' => array(
        'id' => 'cid',
        'label' => 'title',
      ),
      'bundles' => array(
        'mycontenttype' => array(
          'label' => 'My Content Type',
          'admin' => array(
            'path' => 'admin/contenttype',
            'access arguments' => array('administer contenttype'),
          ),
        ),
      ),
      'fieldable' => true,
    ),
  );
  return $return;
}

/**
 * Implements hook_field_extra_fields().
 */
function mycontenttype_field_extra_fields() {
  $return['mycontenttype']['mycontenttype'] = array(
    'form' => array(
      'body' => array(
        'label' => 'Body',
        'description' => t('Body content'),
        'weight' => 0,
      ),
    ),
  );
  return $return;
} 

Then does this go in the .install file?

function mycontenttype_install() {
  $field = array(
    'field_name' => 'body',
    'type' => 'text_with_summary',
    'entity_types' => array('survey'),
    'translatable' => TRUE,
  );
  field_create_field($field);

  $instance = array(
    'entity_type' => 'mycontenttype',
    'field_name' => 'body',
    'bundle' => 'mycontenttype',
    'label' => 'Body',
    'widget_type' => 'text_textarea_with_summary',
    'settings' => array('display_summary' => TRUE),
    'display' => array(
      'default' => array(
        'label' => 'hidden',
        'type' => 'text_default',
      ),
      'teaser' => array(
        'label' => 'hidden',
        'type' => 'text_summary_or_trimmed',
      ),
    ),
  );
  field_create_instance($instance);
}

Answer

Dave Reid picture Dave Reid · Jan 16, 2011

I think your problem is that if node module is installed, there is already a field named 'body'. You should either re-name your field to something like 'mycontenttype_body' (comment.module uses comment_body), or re-use the 'body' field and skip the adding the field part and skip to adding the instance of it. The former is recommended over the latter.