Drupal’s Entity API is one of its most powerful features, allowing developers to define custom data structures that integrate seamlessly with the rest of the system. In this tutorial, we’ll walk through how to create a fieldable custom content entity in Drupal 10/11.
🧠 Why Use a Custom Entity?
While content types (nodes) are great for most use cases, sometimes you need:
- A lightweight data structure without the overhead of nodes
- A custom database schema
- Custom permissions, routes, or workflows
That’s where custom entities shine.
🛠️ Step-by-Step Guide
1. Create a Custom Module
Let’s call it product_entity.
Shell
mkdir -p modules/custom/product_entity/src/Entity
Show more lines
Create product_entity.info.yml:
YAML
name: ‘Product Entity’
type: module
description: ‘Provides a custom fieldable Product entity.’
core_version_requirement: ^10 || ^11
package: Custom
dependencies:
– field
Show more lines
2. Define the Entity Class
Create src/Entity/Product.php:
PHP
namespace Drupal\product_entity\Entity;
use Drupal\Core\Entity\ContentEntityBase;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
/**
* Defines the Product entity.
*
* @ContentEntityType(
* id = “product”,
* label = @Translation(“Product”),
* base_table = “product”,
* entity_keys = {
* “id” = “id”,
* “label” = “name”
* },
* handlers = {
* “view_builder” = “Drupal\Core\Entity\EntityViewBuilder”,
* “list_builder” = “Drupal\Core\Entity\EntityListBuilder”,
* “form” = {
* “add” = “Drupal\Core\Entity\ContentEntityForm”,
* “edit” = “Drupal\Core\Entity\ContentEntityForm”,
* “delete” = “Drupal\Core\Entity\ContentEntityDeleteForm”
* }
* },
* field_ui_base_route = “entity.product.settings”
* )
*/
class Product extends ContentEntityBase {
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
$fields = parent::baseFieldDefinitions($entity_type);
$fields[‘name’] = BaseFieldDefinition::create(‘string’)
->setLabel(t(‘Product Name’))
->setRequired(TRUE)
->setSettings([
‘max_length’ => 255,
]);
return $fields;
}
}
Show more lines
3. Add Schema
Create config/schema/product_entity.schema.yml:
YAML
product.settings:
type: config_object
label: ‘Product settings’
Show more lines
4. Enable Field UI
Add this to your annotation:
PHP
field_ui_base_route = “entity.product.settings”
Show more lines
Now you can add fields via the admin UI!
5. Install and Test
Enable your module:
Shell
drush en product_entity
Show more lines
Visit /admin/structure → You’ll see your new Product entity ready to use and extend.
✅ What You’ve Learned
- How to define a custom content entity
- How to make it fieldable
- How to integrate it with Drupal’s admin UI
💬 Final Thoughts
Custom entities are a powerful way to build structured, scalable, and reusable data models in Drupal. Mastering them sets you apart as a serious backend developer.