• Home
  • Contact
drupal-doc.png

Creating a content entity type in Drupal 8

Jesus Manuel Olivas
June 26, 2014

Based on requirements of a couple projects that I am currently working on, I was in the need to create a content entity type in Drupal 8, and as usual I decided to go ahead and do what every developer does, RTFM and follow the steps as shown on the official documentation.

I was lucky enough to found a link related to my task “Creating a content entity type in Drupal 8” on the official documentation but since code on a project at Alpha state changes a lot the documentation was not up to date, it means the official documentation is the code and as you can guess I faced some challenges that I will list below and the approach I used to overcome it.

While creating this blog post the documentation was update so you can see the original documentation I was reading when started writing this blog post https://www.drupal.org/node/2192175/revisions/7222609/view the only change so far is the migration from PSR-0 to PSR-4 as you can see it here https://www.drupal.org/node/2192175/revisions/7382233/view

Copy source code from documentation

First task was to copy all the source code from the documentation and this was the result

foo_bar/ ├── README.md ├── foo_bar.info.yml ├── foo_bar.install ├── foo_bar.local_actions.yml ├── foo_bar.local_tasks.yml ├── foo_bar.module ├── foo_bar.routing.yml └── lib └── Drupal └── foo_bar ├── Entity │   ├── Controller │   │   └── FooBarListBuilder.php │   ├── FooBar.php │   └── Form │   ├── FooBarDeleteForm.php │   ├── FooBarFormController.php │   └── FooBarSettingsForm.php └── FooBarInterface.php 6 directories, 13 files

Update to PSR-4

As you can see the directory structure is based on PSR-0 but Drupal modules must be PSR-4 so I updated with the following result.

foo_bar/ ├── README.md ├── foo_bar.info.yml ├── foo_bar.install ├── foo_bar.local_actions.yml ├── foo_bar.local_tasks.yml ├── foo_bar.module ├── foo_bar.routing.yml └── src ├── Entity │   ├── Controller │   │   └── FooBarListBuilder.php │   ├── FooBar.php │   └── Form │   ├── FooBarDeleteForm.php │   ├── FooBarFormController.php │   └── FooBarSettingsForm.php └── FooBarInterface.php 4 directories, 13 files

The "foo_bar" entity type did not specify a list_builder class

After installing the module and trying to visit the route "foo-bar/list" the following error was triggered.

Uncaught PHP Exception Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException: "The "foo_bar" entity type did not specify a list_builder class." at /core/lib/Drupal/Core/Entity/EntityManager.php line 293

Fix: Replace on "src/Entity/FooBar.php" class at the plugin controllers declaration "list" with "list_builder" and since "FooBarListController" class does not exist, point it to the correct class "FooBarListBuilder"

- "list" = "Drupal\foo_bar\Entity\Controller\FooBarListController", + "list_builder" = "Drupal\foo_bar\Entity\Controller\FooBarListBuilder",

After this changes the route "foo-bar/list" was properly working

ContentEntityFormController class not found

When trying to add new content using the follwing route "foo-bar/add" the following error was triggered

PHP Fatal error: Class 'Drupal\Core\Entity\ContentEntityFormController' not found in /modules/foo_bar/src/Entity/Form/FooBarFormController.php on line 12

Fix: "ContentEntityFormController" class not longer exist it was repalced with "ContentEntityForm" then the next step was to replace it on "FooBarFormController" class

-use Drupal\Core\Entity\ContentEntityFormController; +use Drupal\Core\Entity\ContentEntityForm; -class FooBarFormController extends ContentEntityFormController { +class FooBarFormController extends ContentEntityForm {

After this changes the route "foo-bar/add" was properly working

Integrity constraint violation: 1048 Column "type" cannot be null

When trying to save the values in the form and click save the following error was triggered

Uncaught PHP Exception Drupal\Core\Entity\EntityStorageException: "SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'type' cannot be null

Fix: Set "type" form field default value as Entity Type Id at "form" method on "FooBarFormController" class

+ $form['type'] = array( + '#type' => 'hidden', + '#default_value' => $entity->getEntityTypeId(), + );

Call to a member function toRenderArray() on a non-object

When trying to delete any content using "foo-bar/{id}/delete" the following error was triggered

PHP Fatal error: Call to a member function toRenderArray() on a non-object in /core/lib/Drupal/Core/Form/ConfirmFormHelper.php on line 44

Fix: Return an URL object on getCancelRoute method at "FooBarDeleteForm" Class

+use Drupal\Core\Url; - return array( - 'route_name' => 'foo_bar.list', - ); + return new Url('foo_bar.list');

After this changes the route "foo-bar/{id}/delete" was properly working and I was able to delete content

Update the documentation

Finally after the code was properly working you can get the latest version at this github repository https://github.com/jmolivas/foo_bar

I decide to update the documentation with the generated code, you can see the updated version here https://www.drupal.org/node/2192175/revisions/7382931/view

Feel free to send any corrections, improvements or comments related to the new code.

We are CMS specialist and Headless is our passion

Our team has several years of experience working with traditional CMS as Drupal and Wordpress and more than a couple of years using those systems as Headless CMS and providing integrations with modern front-end tools as GatsbyJS, NextJS and others.
Let's talk