- Part 1: Overview of Content and Config Entities in Drupal 8
- Part 2: Most Simple Entity with Bundles
- Part 3: Simple Content Entity with Bundles
- Part 4: Practical Content Entity with Bundles
Quick confession: This is actually not the “most” simple version of a custom entity. You don’t necessarily need a to provide a custom permission. You could instead use an existing permission. Additionally, all of the annotations shown in the following example don’t need to be stated explicitly (especially
handlers[form]), as they will automatically use the default core values when not present. I choose to specify each annotation to help me better understand what is going on.
Now, let’s create an extremely simple custom entity that is fieldable and has bundles. To do so, we’re going to need a few things:
- Custom permission – Alternatively, you could use an existing Drupal permission.
- Content Entity – In this case, named “Most Simple”.
- Config Schema – Details how the config entity is stored within the database.
- Config Entity – In this case, named “Most Simple Type”.
- Config Entity Form – Custom default/add/edit form for the Config Entity.
This is pretty straight forward. Just create
MODULENAME.permissions.yml file in the module and provide a new permission.
config/MODULENAME.schema.yml file within the module, and define the details for our Config Entity.
Besides annotations, you might be surprised how little PHP code it takes to create a very simple Content Entity. That is because of the magic that happens behind the scenes. Take a look.
The Magic of
Aside from the annotation this file only has 3 lines of PHP. A namespace for this class, the import for the extending the
ContentEntityBaseclass, and the custom class definition itself. But due to extending the
ContentEntityBase, there is much more going on in the background when this class is instantiated.
Installation – On installation of the module containing this entity, the
base_table will be created and the class’s “Base Fields” will define the columns for that table. But if you read closely, you’ll notice that we didn’t define anything in the annotation called “base fields”… so where are they coming from?
Base Field Definitions – The parent class
ContentEntityBase has a static method named
baseFieldDefinitions that is called at various times throughout Drupal core. Inside this method, it automatically looks for specific
entity_keys and added them as base fields.
ContentEntityBase will automatically create field definitions for:
You can also override the
baseFieldDefinitions method in your own class to provide additional base fields. I’ll do this in a later example.
Creating a very simple Config Entity also requires very little PHP. Most of the work is done by Drupal parsing the annotation.
The main differences to note between this Config Entity and the previous Content Entity are the new annotation properties (described in the examples at the top of this post), and the new form handlers. For a Config Entity, you’ll need to provide a custom class for the form handlers (explained below).
The Magic of
ConfigEntityBundleBasedoes not have a constructor that provides a lot of behind the scenes magic. Most of the methods in this base class are related to operations that are performed on the entity, such as the
Config Entity Form
As previously mentioned, we need to create our own form class for Config Entities. The reason for this is because
ConfigEntityBundleBase does not magically turn our
entity_keys into fields.
If you haven’t created a custom form for the config entity and you go to create an entity through the UI, there will be no fields in which to provide values for our
entity_keys and the form will not save.
In the custom Config Entity Form we define two methods;
save(). The form method simply provides fields for the
entity_keys defined in the annotation, and the save method simply saves the entity and redirects the user with a message.
That’s it! We now have a very simple Content Entity that has Bundles! Unfortunately, the user experience for managing these entities is terrible.
- No navigation. You must browse directly to the entity management URLs
- Few messages telling us what happened. The only message we’ve created is when saving the Config Entity.
- Few redirects dealing entities. The only redirect we’ve created is when saving the Config Entity
- No practical information on the entity lists. If you were to navigate to the “collection” routes for these entities, all you would see is a list of operations for each entity. You can’t even tell which entity is which. We’ll fix this in the next example by adding ListBuilders to our module.
Luckily, most of these problems are pretty easy to fix…