Create a a documentation page for creating a content entity type via a single PHP file

Created on 24 August 2022, almost 3 years ago
Updated 10 March 2023, about 2 years ago

Documentation location/URL

https://www.drupal.org/docs/drupal-apis/entity-api/creating-a-content-en...

Problem/Motivation

Current article provides too much steps to create a custom content entity type: Permissions, Routing, Interfaces, Controllers, Field settings,
Access control handler.

I understand that those steps are important to know for developers, but a cursory glance at the article with so much actions intimidates inexperienced developers from creating a custom entity, and many of them prefer to create just a new Node Bundle (the bad, but easiest way to create content with custom fields), instead of tinkering with creating many files by the article!

But Drupal Core already provides ready to reuse classes for most of described additional files! So we can describe a custom content entity type with all UI in a single file!

Proposed resolution

Create a separate (or child) page with an article about creation of a content entity type via a single PHP file. I've published the article about this in my own blog here https://korepov.pro/infobase/drupal/22 - we can just copy-paste it as a quick start.

It seems to me that providing such article will show the way to quickly create new content entity types without a lot of new files, that will encourage more developers to start creating new entity types with less fear, instead of using Node Bundles for custom content.

So here is my example of self-sufficient single-file Entity Type declaration:


namespace Drupal\my_module\Entity;

use Drupal\Core\Entity\ContentEntityBase;
use Drupal\Core\Entity\EntityPublishedInterface;
use Drupal\Core\Entity\EntityPublishedTrait;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Entity\EntityTypeInterface;

/**
 * Defines the MyCustomItem entity.
 *
 * @ingroup my_module
 *
 * @ContentEntityType(
 *   id = "my_module_item",
 *   label = @Translation("My module item"),
 *   base_table = "my_module_item",
 *   entity_keys = {
 *     "id" = "id",
 *     "published" = "status",
 *   },
 *   handlers = {
 *     "access" = "Drupal\entity\EntityAccessControlHandler",
 *     "form" = {
 *       "add" = "Drupal\Core\Entity\ContentEntityForm",
 *       "edit" = "Drupal\Core\Entity\ContentEntityForm",
 *       "delete" = "Drupal\Core\Entity\ContentEntityDeleteForm",
 *     },
 *     "list_builder" = "Drupal\Core\Entity\EntityListBuilder.php",
 *     "local_action_provider" = {
 *       "collection" = "Drupal\entity\Menu\EntityCollectionLocalActionProvider",
 *     },
 *     "permission_provider" = "Drupal\entity\EntityPermissionProvider",
 *     "route_provider" = {
 *       "default" = "Drupal\Core\Entity\Routing\DefaultHtmlRouteProvider",
 *     },
 *     "views_data" = "Drupal\views\EntityViewsData",
 *   },
 *   persistent_cache = TRUE,
 *   translatable = FALSE,
 *   admin_permission = "my_module administer",
 *   links = {
 *     "canonical" = "/admin/structure/my-module-items/{my_module_item}",
 *     "collection" = "/admin/structure/my-module-items",
 *     "add-form" = "/admin/structure/my-module-items/add",
 *     "edit-form" = "/admin/structure/my-module-items/{my_module_item}/edit",
 *     "delete-form" = "/admin/structure/my-module-items/{my_module_item}/delete",
 *   },
 * )
 */
// On Drupal 8.4+ you can also use `extend EditorialContentEntityBase` that
// provides `Changed`, `Published` and `RevisionLog` properties by default.
class MyModuleItem extends ContentEntityBase implements EntityPublishedInterface {

  // You can remove `implements EntityPublishedInterface`,
  // `EntityPublishedTrait`, `publishedBaseFieldDefinitions() calls, 
  // and `"published" = "status"` annotation, if you don't need 
  // such functionality in your entity type.
  use EntityPublishedTrait;

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

    // Add the published field.
    $fields += static::publishedBaseFieldDefinitions($entity_type);

    $fields['my_custom_string'] = BaseFieldDefinition::create('string')
      ->setRequired(TRUE)
      ->setLabel('My custom string')
      ->setSettings([
        'max_length' => 32,
      ]);

    return $fields;
  }

}

Remaining tasks

📌 Task
Status

Active

Component

Missing documentation

Created by

🇦🇲Armenia murz Yerevan, Armenia

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

Production build 0.71.5 2024