Entities in Drupal provide a structured way of storing and managing data. With the inclusion of Entity API in Drupal 8, it becomes even easier to manage existing, and creating new entities. Similar entities are grouped into Entity Types, which further have subtypes known as Bundles, to which fields can be attached.
For example, the node entity type has two bundles — Articles, and Basic page. The bundles share some common properties and also have some fields that are unique to them.
Drupal core provides with many built-in entity types and also allows us to define custom entity types and bundles. There are two types of entity types — Content Entities and Configuration Entities.
Configuration Entities | Content Entities |
They store data about your Drupal site (metadata) |
They store data on your Drupal site |
Non-Fieldable |
Fieldable |
Non-Revisionable |
Revisionable |
Drupal core includes action, block, block_comment_type, comment_type, contact_type, contact_form, configurable_language, editor, field_storage_config, field_config, filter_format, image_style, menu, language_content_settings, migration, node_type, rdf_mapping, search_page, response_image_style, taxonomy_vocabulary, shortcut_set, tour, user_role, and view |
Drupal core includes aggregator_feed, aggregator_item, block_content, comment, contact_message, file, node, menu_link_content, shortcut, taxonomy_term, and user |
When to use Custom Entities?
Before actually defining custom entity types, let us understand the situations where they should be used:
- Boost in Performance
In most cases, nodes can be used to store any kind of content. However, nodes implement tons of hooks and add the functionalities that might not be required. Moreover, all the content data is stored in a single database table. This can cause performance issues when the number of content items increases. Here, custom entities can be used to boost performance.
- Build a better admin UX
At times, it is necessary to provide better administration forms and menus for the site builders as well as the content editors. The menus, paths, and form displays can be configured as required.
- Defining custom functionalities
We can implement custom methods to our entity types, add custom menu items, and paths. We may also define custom data storage and workflows as per requirements.
Custom entity types allow us to define custom functionality, boost performance, and have total control over the structure of data, admin menus, paths, and storage schema.
Creating a Custom Entity using Drupal Console
To define custom entities, we must create a module and then add a custom entity. Drupal Console can be used to generate most of the boilerplate code, however, some knowledge of object-oriented programming, PHP, and YML is required to be able to add custom functionality to our entity.
Let's consider an example of a Book entity with the following properties — Title, ISBN, Author(s), and Price, with two bundles or subtypes — EBook (File size, Download URL) and PaperBook (Weight, In Stock).
- Navigate to the root directory of your Drupal site.
$ cd /var/www/html/drupal8
-
Generate module boilerplate using Drupal Console.
$ drupal generate:module
-
Answer a series of questions generated by the module generator.
// Welcome to the Drupal module generator Enter the new module name: > Books Enter the module machine name [books]: > Enter the module Path [modules/custom]: > Enter module description [My Awesome Module]: > Provides custom entity to store information about books Enter package name [Custom]: > Enter Drupal Core version [8.x]: > Do you want to generate a .module file? (yes/no) [yes]: > Define module as feature (yes/no) [no]: > Do you want to add a composer.json file to your module? (yes/no) [yes]: > Would you like to add module dependencies? (yes/no) [no]: > Do you want to generate a unit test class? (yes/no) [yes]: > no Do you want to generate a themeable template? (yes/no) [yes]: > no Do you want proceed with the operation? (yes/no) [yes]: > Generated or updated files Generation path: /var/www/html/drupal8 1 - /var/www/html/drupal8/modules/custom/books/books.info.yml 2 - /var/www/html/drupal8/modules/custom/books/books.module 3 - /var/www/html/drupal8/modules/custom/books/composer.json Generated lines: "43"
-
Generate custom entity using Drupal Console. For this example, we are creating a content entity type. Configuration entity type can be created using drupal generate:entity:config
$ drupal generate:entity:content
-
Answer a series of questions generated by the entity generator.
// Welcome to the Drupal Content Entity generator Enter the module name [addtoany]: > books Enter the class of your new content entity [DefaultEntity]: > BookEntity Enter the machine name of your new content entity [book_entity]: > Enter the label of your new content entity [Book entity]: > Enter the base-path for the content entity routes [/admin/structure]: > Do you want this (content) entity to have bundles? (yes/no) [no]: > yes Is your entity translatable? (yes/no) [yes]: > Is your entity revisionable? (yes/no) [yes]: > // generate:entity:config Enter the base-path for the config entity routes [/admin/structure]:> Generated or updated filesGeneration path: /var/www/html/drupal8 1 - modules/custom/books/books.permissions.yml 2 - modules/custom/books/books.links.menu.yml 3 - modules/custom/books/books.links.task.yml 4 - modules/custom/books/books.links.action.yml 5 - modules/custom/books/src/BookEntityAccessControlHandler.php 6 - modules/custom/books/src/BookEntityTranslationHandler.php 7 - modules/custom/books/src/Entity/BookEntityInterface.php 8 - modules/custom/books/src/Entity/BookEntity.php 9 - modules/custom/books/src/BookEntityHtmlRouteProvider.php 10 - modules/custom/books/src/Entity/BookEntityViewsData.php 11 - modules/custom/books/src/BookEntityListBuilder.php 12 - modules/custom/books/src/Form/BookEntitySettingsForm.php 13 - modules/custom/books/src/Form/BookEntityForm.php 14 - modules/custom/books/src/Form/BookEntityDeleteForm.php 15 - modules/custom/books/book_entity.page.inc 16 - modules/custom/books/templates/book_entity.html.twig 17 - modules/custom/books/src/Form/BookEntityRevisionDeleteForm.php 18 - modules/custom/books/src/Form/BookEntityRevisionRevertTranslationForm.php 19 - modules/custom/books/src/Form/BookEntityRevisionRevertForm.php 20 - modules/custom/books/src/BookEntityStorage.php 21 - modules/custom/books/src/BookEntityStorageInterface.php 22 - modules/custom/books/src/Controller/BookEntityController.php 23 - modules/custom/books/templates//book-entity-content-add-list.html.twig 24 - modules/custom/books/books.module 25 - modules/custom/books/books.module 26 - modules/custom/books/config/schema/book_entity_type.schema.yml 27 - modules/custom/books/books.links.menu.yml 28 - modules/custom/books/books.links.action.yml 29 - modules/custom/books/src/Entity/BookEntityTypeInterface.php 30 - modules/custom/books/src/Entity/BookEntityType.php 31 - modules/custom/books/src/BookEntityTypeHtmlRouteProvider.php 32 - modules/custom/books/src/Form/BookEntityTypeForm.php 33 - modules/custom/books/src/Form/BookEntityTypeDeleteForm.php 34 - modules/custom/books/src/BookEntityTypeListBuilder.php Generated lines: "1978"
-
Drupal Console has generated the module under modules/custom/books. Now, to add custom properties to the Book entity type, open up the file modules/custom/books/src/Entity/BookEntity.php in any IDE or text editor and add the following lines of code under the baseFieldDefinitions method of the class BookEntity.
$fields['isbn'] = BaseFieldDefinition::create('integer') ->setLabel(t('ISBN')) ->setDescription(t('ISBN of the Book')) ->setRevisionable(TRUE) ->setTranslatable(TRUE) ->setDisplayOptions('form', array( 'type' => 'string_textfield', 'settings' => array( 'display_label' => TRUE, ), )) ->setDisplayOptions('view', array( 'label' => 'hidden', 'type' => 'string', )) ->setDisplayConfigurable('form', TRUE) ->setRequired(TRUE); $fields['author'] = BaseFieldDefinition::create('string') ->setLabel(t('Author')) ->setDescription(t('Author(s) of the book')) ->setRevisionable(TRUE) ->setTranslatable(TRUE) ->setDisplayOptions('form', array( 'type' => 'string_textfield', 'settings' => array( 'display_label' => TRUE, ), )) ->setDisplayOptions('view', array( 'label' => 'hidden', 'type' => 'string', )) ->setDisplayConfigurable('form', TRUE) ->setRequired(TRUE); $fields['price'] = BaseFieldDefinition::create('float') ->setLabel(t('Price')) ->setDescription(t('Price of the Book')) ->setRevisionable(TRUE) ->setTranslatable(TRUE) ->setDisplayOptions('form', array( 'type' => 'string_textfield', 'settings' => array( 'display_label' => TRUE, ), )) ->setDisplayOptions('view', array( 'label' => 'hidden', 'type' => 'string', )) ->setDisplayConfigurable('form', TRUE) ->setRequired(TRUE);
-
Various other aspects of the entity can be customized such as admin menus, paths, and forms, constraints and properties can be applied to the fields. Refer to the docs for a complete reference. For now, let’s install the newly created module.
$ drush en books -y
or
$ drupal module:install books
In case you make any changes to the entity after installing the module, make sure to run the drupal update:entities to apply the updates.
Creating Bundles and Adding Fields to Them
Bundles can be created and fields can be attached to them using the UI.
- Navigate to Manage → Structure and click on “Add Book Entity type”
- Add a suitable label and click on “Save”
- Click on “Manage Fields” from the drop-down menu and add fields to the bundle as required.
- Repeat this process for all the bundles
You can now create entities of your custom entity types. By default, the menu for creating a new entity will be present under admin/structure/{your-custom-entity}.This can be altered by changing the parent key under entity.book_entity.collection in the modules/custom/books/books.links.menu.yml file.
Conclusion
Entities are building blocks and integral of a Drupal site. Custom entity types allow us to define custom functionality, boost performance, and have total control over the structure of data, admin menus, paths, and storage schema. They can be created with little or no effort using the Drupal Console.
Let us know in the comments below how your custom entity helped you out. Or hit us up at [email protected] for more such tutorials.
Subscribe
Related Blogs
SDC: Integrating Storybook & Single Directory Component
Today, we will talk about about Drupal Single Directory Components or SDC and Storybook. Single Directory Components in Drupal allows you…
RFP: How To Create An RFP For Open Source Solutions?
A good Request for Proposals (RFP) or Call for Proposals (CFP) clearly states the goals and expectations of your project and sets the…
Drupal 7 End Of Life: Top Reasons You Should Migrate To Drupal 10
Drupal 10 was released in December 2022 and ever since, the community has been pushing its users to do Drupal 7 to 10 migration. As per…