7 system.api.php hook_entity_info()

Inform the base system and the Field API about one or more entity types.

Inform the system about one or more entity types (i.e., object types that can be loaded via entity_load() and, optionally, to which fields can be attached).

Return value

An array whose keys are entity type names and whose values identify properties of those types that the system needs to know about:

  • label: The human-readable name of the type.
  • controller class: The name of the class that is used to load the objects. The class has to implement the DrupalEntityControllerInterface interface. Leave blank to use the DrupalDefaultEntityController implementation.
  • base table: (used by DrupalDefaultEntityController) The name of the entity type's base table.
  • revision table: The name of the entity type's revision table (if any).
  • static cache: (used by DrupalDefaultEntityController) FALSE to disable static caching of entities during a page request. Defaults to TRUE.
  • field cache: (used by Field API loading and saving of field data) FALSE to disable Field API's persistent cache of field data. Only recommended if a higher level persistent cache is available for the entity type. Defaults to TRUE.
  • load hook: The name of the hook which should be invoked by DrupalDefaultEntityController:attachLoad(), for example 'node_load'.
  • uri callback: The name of an implementation of callback_entity_info_uri().
  • label callback: (optional) The name of an implementation of callback_entity_info_label(), which returns the label of the entity. The entity label is the main string associated with an entity; for example, the title of a node or the subject of a comment. If there is an entity object property that defines the label, then using the 'label' element of the 'entity keys' return value component suffices to provide this information (see below). Alternatively, specifying this callback allows more complex logic to determine the label of an entity. See also the entity_label() function, which implements this logic.
  • language callback: (optional) The name of an implementation of callback_entity_info_language(). In most situations, when needing to determine this value, inspecting a property named after the 'language' element of the 'entity keys' should be enough. The language callback is meant to be used primarily for temporary alterations of the property value: entity-defining modules are encouraged to always define a language property, instead of using the callback as main entity language source. In fact not having a language property defined is likely to prevent an entity from being queried by language. Moreover, given that entity_language() is not necessarily used everywhere it would be appropriate, modules implementing the language callback should be aware that this might not be always called.
  • fieldable: Set to TRUE if you want your entity type to accept fields being attached to it.
  • translation: An associative array of modules registered as field translation handlers. Array keys are the module names, array values can be any data structure the module uses to provide field translation. Any empty value disallows the module to appear as a translation handler.
  • entity keys: An array describing how the Field API can extract the information it needs from the objects of the type. Elements:

    • id: The name of the property that contains the primary id of the entity. Every entity object passed to the Field API must have this property and its value must be numeric.
    • revision: The name of the property that contains the revision id of the entity. The Field API assumes that all revision ids are unique across all entities of a type. This entry can be omitted if the entities of this type are not versionable.
    • bundle: The name of the property that contains the bundle name for the entity. The bundle name defines which set of fields are attached to the entity (e.g. what nodes call "content type"). This entry can be omitted if this entity type exposes a single bundle (all entities have the same collection of fields). The name of this single bundle will be the same as the entity type.
    • label: The name of the property that contains the entity label. For example, if the entity's label is located in $entity->subject, then 'subject' should be specified here. If complex logic is required to build the label, a 'label callback' should be defined instead (see the 'label callback' section above for details).
    • language: The name of the property, typically 'language', that contains the language code representing the language the entity has been created in. This value may be changed when editing the entity and represents the language its textual components are supposed to have. If no language property is available, the 'language callback' may be used instead. This entry can be omitted if the entities of this type are not language-aware.
  • bundle keys: An array describing how the Field API can extract the information it needs from the bundle objects for this type. This entry is required if the 'path' provided in the 'bundles'/'admin' section identifies the bundle using a named menu placeholder whose loader callback returns an object (e.g., $vocabulary for taxonomy terms, or $node_type for nodes). If the path does not include the bundle, or the bundle is just a string rather than an automatically loaded object, then this can be omitted. Elements:

    • bundle: The name of the property of the bundle object that contains the name of the bundle object.
  • bundles: An array describing all bundles for this object type. Keys are bundles machine names, as found in the objects' 'bundle' property (defined in the 'entity keys' entry above). This entry can be omitted if this entity type exposes a single bundle (all entities have the same collection of fields). The name of this single bundle will be the same as the entity type. Elements:

    • label: The human-readable name of the bundle.
    • uri callback: Same as the 'uri callback' key documented above for the entity type, but for the bundle only. When determining the URI of an entity, if a 'uri callback' is defined for both the entity type and the bundle, the one for the bundle is used.
    • admin: An array of information that allows Field UI pages to attach themselves to the existing administration pages for the bundle. Elements:

      • path: the path of the bundle's main administration page, as defined in hook_menu(). If the path includes a placeholder for the bundle, the 'bundle argument' and 'real path' keys below are required.
      • bundle argument: The position of the bundle placeholder in 'path', if any.
      • real path: The actual path (no placeholder) of the bundle's main administration page. This will be used to generate links.
      • access callback: As in hook_menu(). 'user_access' will be assumed if no value is provided.
      • access arguments: As in hook_menu().
  • view modes: An array describing the view modes for the entity type. View modes let entities be displayed differently depending on the context. For instance, a node can be displayed differently on its own page ('full' mode), on the home page or taxonomy listings ('teaser' mode), or in an RSS feed ('rss' mode). Modules taking part in the display of the entity (notably the Field API) can adjust their behavior depending on the requested view mode. An additional 'default' view mode is available for all entity types. This view mode is not intended for actual entity display, but holds default display settings. For each available view mode, administrators can configure whether it should use its own set of field display settings, or just replicate the settings of the 'default' view mode, thus reducing the amount of display configurations to keep track of. Keys of the array are view mode names. Each view mode is described by an array with the following key/value pairs:

    • label: The human-readable name of the view mode
    • custom settings: A boolean specifying whether the view mode should by default use its own custom field display settings. If FALSE, entities displayed in this view mode will reuse the 'default' display settings by default (e.g. right after the module exposing the view mode is enabled), but administrators can later use the Field UI to apply custom display settings specific to the view mode.

See also



Related topics

7 functions implement hook_entity_info()

Note: this list is generated by pattern matching, so it may include some functions that are not actually implementations of this hook.

comment_entity_info in modules/comment/comment.module
Implements hook_entity_info().
entity_cache_test_dependency_entity_info in modules/simpletest/tests/entity_cache_test_dependency.module
Implements hook_entity_info().
field_test_entity_info in modules/field/tests/field_test.entity.inc
Implements hook_entity_info().
node_entity_info in modules/node/node.module
Implements hook_entity_info().
system_entity_info in modules/system/system.module
Implements hook_entity_info().

... See full list

2 invocations of hook_entity_info()
aggregator_form_aggregator_admin_form_alter in modules/aggregator/aggregator.processor.inc
Implements hook_form_aggregator_admin_form_alter().
entity_get_info in includes/common.inc
Get the entity info array of an entity type.


modules/system/system.api.php, line 202
Hooks provided by Drupal core and the System module.


function hook_entity_info() {
  $return = array(
    'node' => array(
      'label' => t('Node'),
      'controller class' => 'NodeController',
      'base table' => 'node',
      'revision table' => 'node_revision',
      'uri callback' => 'node_uri',
      'fieldable' => TRUE,
      'translation' => array(
        'locale' => TRUE,
      'entity keys' => array(
        'id' => 'nid',
        'revision' => 'vid',
        'bundle' => 'type',
        'language' => 'language',
      'bundle keys' => array(
        'bundle' => 'type',
      'bundles' => array(),
      'view modes' => array(
        'full' => array(
          'label' => t('Full content'),
          'custom settings' => FALSE,
        'teaser' => array(
          'label' => t('Teaser'),
          'custom settings' => TRUE,
        'rss' => array(
          'label' => t('RSS'),
          'custom settings' => FALSE,

  // Search integration is provided by node.module, so search-related
  // view modes for nodes are defined here and not in search.module.
  if (module_exists('search')) {
    $return['node']['view modes'] += array(
      'search_index' => array(
        'label' => t('Search index'),
        'custom settings' => FALSE,
      'search_result' => array(
        'label' => t('Search result highlighting input'),
        'custom settings' => FALSE,

  // Bundles must provide a human readable name so we can create help and error
  // messages, and the path to attach Field admin pages to.
  foreach (node_type_get_names() as $type => $name) {
    $return['node']['bundles'][$type] = array(
      'label' => $name,
      'admin' => array(
        'path' => 'admin/structure/types/manage/%node_type',
        'real path' => 'admin/structure/types/manage/' . str_replace('_', '-', $type),
        'bundle argument' => 4,
        'access arguments' => array('administer content types'),

  return $return;


If you find yourself scratching your head having read this page, head on over to the Field Attach API page for a little bit more clarity.

Note that even though the documentation for the label callback key tells you to look at entity_label() as an example, the parameters of that function are actually the reverse of the parameters passed to your entity's label callback.

For view modes, re:

Keys of the array are view mode names. ...

I found in Drupal 7.7 and 7.8-dev that the view mode key must only contain alphanumeric characters with no punctuation such as underscores (i.e. productselection works, while product_selection does not). An underscore in the key of my custom view mode caused the display mode to be displayed but not configurable in Structure > Content types (Manage display). Maybe this is a bug I should open an issue for?

Did you enable that view mode to have custom settings on the 'Default' page under Manage display?

A little more on label callback: the second parameter seems to consistently be a string of the entity type, but for some reason I'm finding that the first parameter is sometimes an integer of the entity id, sometimes the object of the entity. I've not yet figured out what's going on, my best guess based on what I'm seeing is that maybe it's the ID if the entity hasn't yet been loaded with entity_load(); and the object if it has. This fits the behaviour I'm seeing but seems odd.

Might it be assumed that the 'label' field is required, even if the 'label callback' is defined? That isn't clear.

load hook (optional) ....

I've spent hours strugging with drupal APIs such as form API, field API.. I had to use xdebug to know how things work because the documentation isn't really one in most of the cases, and you find your self struggling with line of codes (note that drupal overly uses keyed array with no appropriate doc).

Now i'd like to build an entity that is fieldable and that does not support bundle except tne default one which is itself. That means I'd like this entity to be fieldable via the field administration UI (as for node bundles) => http://your-site/admin/structure/types/manage/your-bundle/fields

Does someone know how to make this without having to write hundred lines of codes in which case I'd better develop it from scratch. I keep thinking drupal entity API solely allow us to use abstract ourself from querying the database to load our entity and does not bring any other features ...

What's are the pros of using this instead of writing a module from scratch if we just want a CRUD form for an entity ?

I had the same problem. Here's what I did:
Declare the default bundle admin:

$entity_info[ENTITY_NAME]['bundles'][ENTITY_NAME] = array(
  'label' => t('Entity Name'),
  'admin' => array(
  'path' => 'path/to/admin',
  'access arguments' => array('administer ENTITY TYPE'),

Then I declared a default settings form in hook_menu:

  $items['path/to/admin'] = array(
    'title' => 'ENTITY settings',
    'description' => 'Configure the settings for the ENTITY TYPE.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('MODULE_NAME_ENTITY_NAME_settings'),
    'access arguments' => array('administer ENTITY TYPE'),
    'weight' => -10,
  $items['path/to/admin/settings'] = array(
    'title' => 'Settings',
    'weight' => -10,

The settings page is necessary because the "Manage Fields" and "Manage Display" are local tasks. You don't have to make the Settings a form, but you can put some entity configuration options there.

Entity API is useful for integrating with other modules (like Rules and Views) and gives you a whole bunch of other useful stuff.

Thank you for your answer. I also found the solution, indeed the admin key in the array makes the whole thing work.

You shouldn’t be leaving home without getting into the EntityAPI module if you want to do anything with entities. This module adds a whole lot of keys to hook_entity_info. You will find all the gory details here:


If you're omitting 'bundles' to get the system to define a single bundle automatically for you, you must not also have ['entity keys']['bundle'] defined.