Drupal Entities, What are they & Custom Types
As developers, time after time, we come across numerous terms that gain a new meaning in the context of which technology we're using them. Moreover, a lot of times, you'll find that certain terms mean one thing on one platform and something else in another!
Drupal, itself, is no different, as it has many different terminologies that are used in the community. Entities are definitely one to consider when picking up on Drupal terminology (not to be confused with entities in the Symfony framework in which Drupal 8 is now built). The term “entity” in Drupal is a term you will not necessarily come across often if at all if you're just site building. It is a term used mostly for the development aspect of Drupal to describe data.
What are Entities?
So the question in mind is basically "What is an entity?" Before answering that question in the context of Drupal, let's first take a look at the actual meaning of the word entity. The Merriam-Webster definition is rendered as "the existence of a thing as contrasted with its attributes". This definition is very helpful when defining Drupal entities because that is basically what they are.
You could say...Drupal entities are pieces of content or data that have different attributes or metadata associated with it.
Yep, they are just individual items with unique attributes. Let's take application developers for example. They are all individuals with a set of abilities and attributes. They have specific goals or purposes they work to fulfill. Some develop applications for the web, some for desktops and laptops, and others for mobile devices, such as tablets and phones.
To drill deeper, we also have multiple varieties of application developers for each of the mentioned mediums. For the web, you can have front-end and back-end developers. Mobile developers often develop for specific operating systems like Android or iOS. You may also notice many applications that are only built for computers running Windows.
As you can see, although all of the groups mentioned above are still application developers, they do things differently and for different reasons using their varying abilities.
Entities are like individual "application developers" that have abilities and attributes (or fields) associated with them to fulfill a purpose. There are different types in which these abilities and attributes vary, and thus do a variety of different things. These types are referred to as entity types.
Drupal, as you may have imagined, comes with default entity types. As of the Drupal 8 releases, some of these are node (content), taxonomy term, user, comments, block, file, and the list continues. They all serve different purposes. The node entity type is intended specifically for the output of content where taxonomy term is meant for the grouping of content. Any instance of these entity types created with data input as defined by that entity type are individual entities.
Entities can also have subtypes, known as bundles. Entity types can further be divided into sub-groups with specific types of data for each while still maintaining overall the same functionality. For example, bundles for the node entity type are called content types and allow a user to define a specific set of fields for each. Drupal.org outlines the bundles for Drupal's core entities and even provides a diagram or map of the entities.
Based on the illustration above, a similar diagram would look like this:
- Mobile Developers
- Bundles: Platforms
- Bundles: Platforms
- Web Developers
- Bundles: Developer Type
- Full Stack
- Bundles: Developer Type
Where did they come from?
Entities were initially introduced in Drupal 7 allowing content such as taxonomy terms and comments to receive fields via the new field API. Before Drupal 7, custom fields were added through the UI by way of a contributed module known as the Content Construction Kit (CCK). At that time, fields could only be added to nodes. As Drupal began to move away from a "page" centric view to a more "data" centric view, the concept of entities was created in D7 and a lot of the field functionality from the CCK module was used in the field API.
Now as of Drupal 8, more things than ever are entities giving site builders and developers more power to customize their projects to their particular needs!
Why are they necessary?
Entities in Drupal 8 allow us to attach fields to and thus customize the output of different things, such as blocks and users, which was previously not possible. It gives us more control over the data we use throughout our projects and how we display it.
More entity types can be added by contributed modules, such as the Paragraphs module that adds the Paragraph entity type or the Media module which adds the Media entity type, both of which have unique capabilities. Moreover, you can add entity types of your own!
And there you have it!
Drupal entities are just individual items that can be used in different ways to do a variety of things.
Hopefully, you have gained a better understanding of Drupal entities. There is one more thing. As mentioned earlier, entity types can be added by contributed modules, which means Drupal allows for the creation of more.
Why would we ever need to do that? In fact, how would we build an entity type ourselves?
Glad you asked!
Why would we ever need to Build an entity type?
First, let us ask ourselves why we would need to create our own. As mentioned, Drupal comes with many configurations and content entities in Core. They, themselves, cover most of the needs you would have for a site. Users, pages, categories, page components, etc. You name it, there is an entity type already available to fulfill that purpose. Moreover, if Core does not have what you need, it is more than likely available as a contributed module. Take the Media entity for example, as mentioned in Part one of this post. It is a contributed module that provides a custom entity for handling various forms of media such as images and videos. As of Drupal 8.4, the media entity has been included in Core.
With these things in mind, there is little reason we would ever have to make one on our own. But just think, those contributed modules providing entity types exist for a reason. Someone felt there was a need to provide a custom solution to whatever the custom entity provides.
As you work on bigger Drupal solutions, you will discover you may be in a similar boat. The entity types in Core may not provide you with the functionality you need or it may simply not make sense for you to leverage an existing entity type for your issue. Take the Webform module as an example. As a contributed module, it provides a custom entity type that can display webforms on the frontend. Not only would it not make sense to leverage a Core entity type to fulfill this functionality, such as node, taxonomy term, user, etc. but it would not be possible since these entity types do not have this functionality.
So you can't use a core entity type to fulfill your purpose but surely there must be a contributed module out there. Given how unique one's needs could be, there might not be. But if there is, there is a chance it is not for your version of Drupal, poorly maintained, or adds too much extra functionality.
It is situations similar to this where you could decide to make your own. Well, how do we do that?
Make it from Scratch?
You could make it from scratch writing every line of code, creating every file on your own. Unfortunately, if you take this route, considering how complex even the simplest of entity types can be code-wise, it would be time-consuming and more prone to error. It is for this reason you'd see many people suggest using Drupal Console to generate one for you.
The drupal generate:entity:content is what you'll use to generate the content entity type. Before doing that, you'd want to create a module which you can also generate using Drupal Console's drupal generate: module.
Once you set up your module, you can begin generating your custom content entity type.
In this example, using the analogy from the previous post, we'll be creating a custom entity type called "Web Developer". This will be inside of a module called "Developer". You can place any number of content entity types within a module but it is usually good to limit it to one and name the module after the entity type. In this case, we'll be adding two, but we'll get to the second one later.
When running drupal generate:entity:content or drupal geco, you will be asked a series of questions that will aid Drupal Console in getting a base structure set up for your entity type.
The first question, "Enter the module name" refers to the module the entity type should be housed. In our case, this would be the "Developer" module. The main part of the custom entity type is the definition plugin. It is a class that will be in a file, in our case, called WebDeveloper.php inside of the /src/Entity directory of your module. The file is named after the class it contains.
Another prompt asks you to "Enter the base-path for the content entity routes". As an entity type, your content entity will have routes for various things, such as viewing an entity, adding one, a bundle listing page, etc. Drupal Console will often have defaults for these prompts in which you can just press enter without typing anything if the default satisfies your needs. The default for base-path is /admin/structure. In most cases, this will be fine so we will leave it as is. We should note the fact that this command simply generates the code we need for our custom entity type. We can go in and edit these items in code later.
The rest of the prompts should be self-explanatory enough. For our example, the prompt asking if you'd like your entity to have bundles should be marked as "yes" as our entity type will have bundles. It is "no" by default. As a side note, Bundles are actually a config entity type. We are creating two entity types if our content entity type has bundles.
After going through all the prompts, your entity type's files will be generated.
Here's an example of the process:
Once you install your module, your entity type will be ready to use. From there, you can add your bundles.
We now have our Web Developer entity type. Now try creating one for Mobile Developers and try different options to see what Drupal Console gives you.
Is that all? Maybe, maybe not. It depends on your needs. Although, if you have decided to create an entity type, to begin with, there will most likely be some customizations involved.
There are many customizations that can be made. Drupal Console just serves as a way of getting the necessary code set up quickly.
Check out this post on drupal.org that goes deeper into this subject and has many code examples.
We look forward to going over some of the cool things that can be done with content entity types in the future!