Drupal is a registered trademark of Dries Buytaert
Protected Pages 3.0.0 Major update available for module protected_pages (3.0.0). Commerce Core 3.3.8 Minor update available for module commerce (3.3.8). Search API HTML Element Filter 1.0.7 Minor update available for module search_api_html_element_filter (1.0.7). Layout Builder Reorder 2.0.1 Minor update available for module layout_builder_reorder (2.0.1). Ban 1.1.0 Minor update available for module ban (1.1.0). Field Formatter Range 2.0.0 Major update available for module field_formatter_range (2.0.0). Field Formatter Range 8.x-1.8 Minor update available for module field_formatter_range (8.x-1.8). Varbase Media Header 9.2.1 Minor update available for module varbase_media_header (9.2.1). Search API Solr 4.3.11 Module search_api_solr updated after 14 months of inactivity (4.3.11). Provus Mega Menu Module provus_mega_menu crossed 1,000 active installs.

Child Entity

5 sites Security covered
View on drupal.org

This module allows you to create entities that are dependent on a parent entity, meaning they can only exist in relation to a specific parent. For example, a "room" entity might always belong to a "house" entity. It provides traits and interfaces to easily implement this parent-child relationship in your custom entities.

This module helps you to create Entities which creating them depends on a parent entity.

Consider a Room in a House. The Room can only every be in one house. In this example Room is child and House is parent entity.

In order to use this module you have to:

  • Implement ChildEntityInterface or extend it
  • Use Child Entity Handlers, either directly in the Entity definition or extending them.
  • Define parent key in entity_keys section of the child entity annotation and use ChildEntityTrait
  • Add childBaseFieldDefinitions

This works in the same way as core's EntityOwnerTrait.

/**
 ************ other configuration ************
 *   handlers = {
 *     "list_builder" = "Drupal\child_entity\ChildEntityListBuilder",
 *     "views_data" = "Drupal\child_entity\ChildEntityViewsData",
 *     "form" = {
 *       "default" = "Drupal\child_entity\Form\ChildEntityForm",
 *     },
 *     "route_provider" = {
 *       "html" = "Drupal\child_entity\Routing\ChildEntityHtmlRouteProvider",
 *     },
 *     "access" = "Drupal\child_entity\ChildEntityAccessControlHandler",
 *   entity_keys = {
 *     "parent" = "house",
 *   },
 ************ other configuration ************
 */
class Room extends ContentEntityBase implements ChildEntityInterface {

  use ChildEntityTrait;

  /**
   * {@inheritdoc}
   */
  public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
    $fields = parent::baseFieldDefinitions($entity_type);

    $fields += static::childBaseFieldDefinitions($entity_type);

    return $fields;
  }
}

Revision-able Entities and urlRouteParameters()

If your entity type also has revisions you may be overriding the urlRouteParameters() but you need to specify to use the one from the trait:

  use ChildEntityTrait {
    urlRouteParameters as childEntityUrlRouteParameters;
  }

  /**
   * {@inheritdoc}
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  protected function urlRouteParameters($rel) {
    $uri_route_parameters = $this->childEntityUrlRouteParameters($rel);

    if ($rel === 'revision_revert' && $this instanceof RevisionableInterface) {
      $uri_route_parameters[$this->getEntityTypeId() . '_revision'] = $this->getRevisionId();
    }
    elseif ($rel === 'revision_delete' && $this instanceof RevisionableInterface) {
      $uri_route_parameters[$this->getEntityTypeId() . '_revision'] = $this->getRevisionId();
    }

    return $uri_route_parameters;
  }

Version 1

Version 1 of this module implemented Base classes that can be extended however this has limitations and version 2 uses Traits which allows the following:

class ChildNode extends Node implements ChildEntityInterface {

  use ChildEntityTrait;
}

Activity

Total releases
2
First release
Jan 2026
Latest release
5 months ago
Releases (12 mo)
2 ▲ from 0
Maintenance
Active

Releases

Version Type Release date
2.1.x-dev Dev Feb 8, 2026
2.0.0 Stable Jan 25, 2026