
Custom Entity Types in Drupal 10/11

Drupal's real power comes from its Entity API — not just nodes and users. At Arudhra IT Techs, we build fully custom entities like vendors, ratings, bookings, and networks using Drupal 10 and 11. This blog shows how to create your own custom entity type from scratch, complete with admin UI, routes, base fields, and storage.
Custom Entity Types in Drupal 10/11: How We Create Real-World Data Models from Scratch
Drupal isn’t just nodes. If you’re building serious applications like vendor portals, ticketing systems, or SaaS dashboards, you’ll eventually need custom entity types — your own data models with full CRUD, fields, permissions, and routing. Here's how we build them in real projects.
📦 Step 1: Create Your Custom Module
Let’s create a module called wpc_vendor
.
drupal generate:module
Enable it with:
drush en wpc_vendor
🧱 Step 2: Define the Entity Type with Annotation
Create the file src/Entity/Vendor.php
:
namespace Drupal\wpc_vendor\Entity;
use Drupal\Core\Entity\ContentEntityBase;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
/**
* Defines the Vendor entity.
*
* @ContentEntityType(
* id = "vendor",
* label = @Translation("Vendor"),
* base_table = "vendor",
* entity_keys = {
* "id" = "id",
* "label" = "name",
* "uuid" = "uuid"
* },
* handlers = {
* "list_builder" = "Drupal\Core\Entity\EntityListBuilder",
* "form" = {
* "default" = "Drupal\Core\Entity\ContentEntityForm",
* "add" = "Drupal\Core\Entity\ContentEntityForm",
* "edit" = "Drupal\Core\Entity\ContentEntityForm",
* "delete" = "Drupal\Core\Entity\ContentEntityDeleteForm"
* }
* },
* admin_permission = "administer vendor entities",
* links = {
* "canonical" = "/vendor/{vendor}",
* "add-form" = "/vendor/add",
* "edit-form" = "/vendor/{vendor}/edit",
* "delete-form" = "/vendor/{vendor}/delete"
* },
* )
*/
class Vendor extends ContentEntityBase {
public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
$fields['name'] = BaseFieldDefinition::create('string')
->setLabel(t('Vendor Name'))
->setRequired(TRUE)
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
return $fields;
}
}
📊 Step 3: Add Schema and Install File
Create wpc_vendor.install
:
function wpc_vendor_install() {
\Drupal::entityTypeManager()
->getStorage('vendor')
->installSchema('vendor');
}
Also create wpc_vendor.schema.yml
for fields (optional for config).
🛠️ Step 4: Provide Admin UI
Use list builder to show vendors in admin panel.
// Add this to handlers
"list_builder" = "Drupal\wpc_vendor\VendorListBuilder"
// Implement listBuilder at src/VendorListBuilder.php
🧠 Real Use Cases We Built
- 👨💼 Custom Vendor Entity with files, approval status, contact fields
- 📦 Inventory entity with pricing, variations, stock
- 📅 Booking entity with multi-step forms and calendar view
🔐 Permissions and Access
Define in wpc_vendor.permissions.yml
:
administer vendor entities:
title: 'Administer vendor content'
description: 'Full access to vendor data'
🚀 Bonus: Fieldable + Bundle Support
Add:
* bundle_entity_type = "vendor_type",
* field_ui_base_route = "entity.vendor_type.edit_form"
This makes it like content types — with field UI support.
Want a Custom Entity for Your Drupal Project?
Whether it’s vendors, listings, events, ratings, or anything in between — our team builds 100% custom entity types in Drupal 10 and Drupal 11 with routing, fields, REST support, and views integration.
Let us help architect your next project 👇