When learning Drupal development, it won't be long before you encounter the word "entity" and the Entity API. But what are entities in Drupal? How can you use them to build your site? This tutorial will explain Drupal's Entity system from a high level. We'll look at the main problems the Entity system solves, and define the key terms you'll encounter when working with Entities. In case you're already familiar with Drupal's entity system, we'll also take a brief look at the key changes introduced in Drupal 8.
What are entities?
Entities are the basic building blocks of Drupal's data model. They make up, in one way or another, all of the visible content a user interacts with on a Drupal-powered site. There are several types of entities included in Drupal core that make up both the configuration and content of a default installation. It's important to understand the basic differences between these two types of entities before we really dig in further.
Configuration entities are objects that allow us to store information (and default values) for configurable settings on our site. Examples of configuration entities in core include image styles, user roles and displays in views. Configuration entities can be exported via core's configuration management system. They can also be used to provide default configuration used during the installation process or when a new module is enabled. Configuration entities support translation but they cannot have user-configured fields attached to them. The data structure of a configuration entity is limited to what is provided by module code.
Content entities are configurable, support translation and revisions, and allow additional fields to be attached for more complex data modeling. Content entities included in core include nodes, taxonomy terms, blocks and users.
Often you will find entity variants that come in pairs. The Block module, for example, provides configuration entities to define custom block types and content entities to provide the actual content of custom blocks.
Key terms in Drupal's Entity API
Now that we have a little better idea of what Drupal means by the word entity, let's look at some other key terms that we'll need to know in order to understand Drupal's Entity API.
Bundles are another generic noun, used to describe containers for a sub-type of a particular entity. For example, nodes are a type of entity. The node entity has a bundle for each content type (ie: article, page, blog post, etc). Taxonomy is another entity type, and each individual vocabulary is its own bundle. Bundles provide an organizational abstraction layer that allows for differences in field definitions and configurations between entity sub-types. For a particular entity type (i.e. node) all bundles (article, page, etc) will have the same base fields (title, author) but will have different bundle fields (articles have tags).
Fields consist of individual (or compound) data elements that make up the details of the data model. If you're trying to build a photo gallery, your node type will need some method of collecting images. An image field would be handy in this case. Drupal core provides several different types of fields including boolean, decimal, float, integer, entity reference, link, image, email, telephone, and several text fields. Fields, in turn, are built on top of the actual data primitives in Drupal, Typed Data. Fields can be added to content entities and field configuration will vary between bundles of the same entity type.
In short, plugins provide developers an API to encapsulate re-useable behavior. Plugins are used throughout Drupal core and you'll be exposed to several of them while working with the Entity API. We have several tutorials that cover plugins in more depth, starting with What Are Plugins? in our Drupal 8 Module Development Guide.
Annotations are another element of Entity API used throughout Drupal core. Annotations are specially formatted code comments that are parsed to provide metadata information about particular PHP classes to Drupal. The Entity API uses annotations to discover which classes to load for a particular entity type (among other things). You can learn more about how they work in our annotations tutorial.
If you've worked with the Entity API in previous versions of Drupal you're probably already familiar with controllers. Handlers are the Drupal 8 equivalent of Drupal 7's controllers.
Handlers are responsible for acting on and with entities. They help manage things like storage, access control, building lists and views of entities, and the forms required for creating, viewing, updating and deleting entities.
Differences from Drupal 7's Entity API
If you already have experience with the Entity API in previous versions of Drupal and you're familiar with the Entity contrib module much of this probably seems quite familiar. The Entity API was introduced late in the development cycle for Drupal 7. As such it wasn't completely functional on its own. In practice, most implementations either required this contributed module or were left recreating much of its functionality. Drupal 7's version of the Entity API had to account for differences in accessing and working with entity properties (things like the node title and published status) and fields (things like images, reference fields, etc). This interface is unified in Drupal 8 because everything is a field. Developers interact with fields using the same techniques regardless of whether they are base fields or bundle fields. Also the method used for querying entity information, the
EntityFieldQuery class, had limited functionality in core in Drupal 7. The method for querying entities has been simplified in Drupal 8 yet is simultaneously more powerful through chaining.
Here are a few illustrative examples of these differences:
Printing a field value
...in Drupal 7
...in Drupal 8
print $node->field_name->value; $author_name = $node->uid->entity->name->value;
Getting a field definition
...in Drupal 7
$field = field_info_field($field_name); $instance = field_info_instance($entity_type, $field_name, $bundle);
... in Drupal 8
$field_definition = $entity->field_name->getFieldDefinition();
Saving a field value
...in Drupal 7
$node->field_name[LANGUAGE_NONE]['value'] = 'Hello world'; $node->save();
...in Drupal 8
$node->field_name->value = 'Hello world'; $node->save();
The Entity API in Drupal 8 provides the basic organizational mechanisms for creating the site's content model. Since everything in Drupal 8 is an entity, it's important to understand the distinction between configuration and content entities. Likewise, since an entity's properties and values are all fields (base or bundle) we have a unified method of working with them. It's important to understand the relationship between entity types, bundles and fields and how each layer can be used in content modeling.
Further your understanding
- What criteria could you use to decide if you need to implement a configuration or a content entity?
- Can you identify the entity types included in a standard installation of Drupal 8?
- Can you identify the bundles of the node entity type? How about categorizing all of a node's data as either a base field or a bundle field?
- Overview of Configuration (vs. other types of information) (Drupal.org)
- Create a Configuration Entity (Drupalize.Me)
- Entity API implements Typed Data API (Drupal.org)