Creating a custom configuration entity type in Drupal 8

In this tuto, I"ll create an example of how to create a custom configuration entity type, with administration management pages, for Drupal 8. by creating a custom module codimth_entity_config.

Create a Module:

codimth_entity_config/codimth_entity_config.info.yml

In Drupal 8, it is necessary to create an info.yml file that contains the metadata for every custom module.

name: Codimth Entity Config type: module description: 'Provides a ball configuration entity.' package: Custom core: 8.x configure: entity.ball.collection 

codimth_entity_config/codimth_entity_config.routing.yml

The routing.yml file defines the routes for the management pages: list, add, edit, delete, preview and you can add other routes.

entity.ball.collection: path: '/admin/structure/ball' defaults: _entity_list: 'ball' _title: 'ball configuration' requirements: _permission: 'administer ball' entity.ball.add_form: path: '/admin/structure/ball/add' defaults: _entity_form: 'ball.add' _title: 'Add a ball' requirements: _permission: 'administer ball' entity.ball.edit_form: path: '/admin/structure/ball/' defaults: _entity_form: 'ball.edit' _title: 'Edit a ball' requirements: _permission: 'administer ball' entity.ball.delete_form: path: '/admin/structure/ball//delete' defaults: _entity_form: 'ball.delete' _title: 'Delete a ball' requirements: _permission: 'administer ball' entity.ball.preview_page: path: '/admin/structure/ball//preview' defaults: _controller: '\Drupal\codimth_entity_config\Controller\BallController::preview' _title: 'Preview a ball' requirements: _permission: 'administer ball' 

codimth_entity_config/codimth_entity_config.links.action.yml

This makes the "Add ball" link appear on the List page. and in this file you can add other links as you want.

entity.ball.add_form: route_name: 'entity.ball.add_form' title: 'Add ball' appears_on: - entity.ball.collection 

codimth_entity_config/codimth_entity_config.links.menu.yml

in this file you can add a link to the menu.

entity.ball.overview: title: Balls parent: system.admin_structure description: 'List of balls to extend site functionality.' route_name: entity.ball.collection 

codimth_entity_config/codimth_entity_config.permissions.yml

administer ball: title: 'Administer ball' 

codimth_entity_config/config/schema/codimth_entity_config.schema.yml

in this file just add the properties/attributes defined in src/Entity/Ball.php.

codimth_entity_config.ball.*: type: config_entity label: ball mapping: id: type: string label: ID label: type: label label: Label uuid: type: string description: type: string color: type: string point_value: type: string 

codimth_entity_config/src/Entity/Ball.php

This file defines the ball configuration entity class. you can add custom fields as you want.

 * >, * config_prefix = "ball", * admin_permission = "administer ball", * links = < * "collection" = "/admin/structure/ball", * "add-form" = "/admin/structure/ball/add", * "preview-page" = "/admin/structure/ball//preview", * "edit-form" = "/admin/structure/ball/", * "delete-form" = "/admin/structure/ball//delete" * >, * entity_keys = < * "id" = "id", * "label" = "label", * "uuid" = "uuid" * >, * config_export = < * "id", * "label", * "description", * "color", * "point_value" * >* ) */ class Ball extends ConfigEntityBase implements BallInterface < /** * The ball ID. * * @var string */ protected $id; /** * The ball label. * * @var string */ protected $label; /** * The ball status. * * @var bool */ protected $status; /** * The ball description. * * @var string */ protected $description; /** * The color of this ball. * * @var string */ protected $color; /** * The value of this ball measured in points. * * @var integer */ protected $point_value; /** * */ public function getColor() < return $this->color; > /** * */ public function getPointValue() < return $this->point_value; > > 

codimth_entity_config/src/BallInterface.php

Assuming that your configuration entity has properties, you will need to define some set/get methods on an interface.

codimth_entity_config/src/Form/BallForm.php

this file to generate form to add and edit ball entity.

 */ public function form(array $form, FormStateInterface $form_state) < $form = parent::form($form, $form_state); $form['label'] = [ '#type' =>'textfield', '#title' => $this->t('Label'), '#maxlength' => 255, '#default_value' => $this->entity->label(), '#description' => $this->t('Label for the ball.'), '#required' => TRUE, ]; $form['id'] = [ '#type' => 'machine_name', '#default_value' => $this->entity->id(), '#machine_name' => [ 'exists' => '\Drupal\codimth_entity_config\Entity\Ball::load', ], '#disabled' => !$this->entity->isNew(), ]; $form['status'] = [ '#type' => 'checkbox', '#title' => $this->t('Enabled'), '#default_value' => $this->entity->status(), ]; $form['description'] = [ '#type' => 'textarea', '#title' => $this->t('Description'), '#default_value' => $this->entity->get('description'), '#description' => $this->t('Description of the ball.'), ]; $form['color'] = array( '#type' => 'textfield', '#title' => $this->t('Ball Color'), '#default_value' => $this->entity->getColor(), '#size' => 30, '#required' => TRUE, '#maxlength' => 64, '#description' => $this->t('The color of this ball.'), ); $form['point_value'] = array( '#type' => 'textfield', '#title' => $this->t('Point Value'), '#default_value' => $this->entity->getPointValue(), '#size' => 30, '#required' => TRUE, '#maxlength' => 64, '#description' => $this->t('The number of points this ball is worth.'), ); return $form; > /** * */ public function save(array $form, FormStateInterface $form_state) < $result = parent::save($form, $form_state); $message_args = ['%label' =>$this->entity->label()]; $message = $result == SAVED_NEW ? $this->t('Created new ball %label.', $message_args) : $this->t('Updated ball %label.', $message_args); $this->messenger()->addStatus($message); $form_state->setRedirectUrl($this->entity->toUrl('collection')); return $result; > /** * */ protected function actions(array $form, FormStateInterface $form_state) < $actions = parent::actions($form, $form_state); $entity = $this->entity; if (!$entity->isNew()) < $actions['preview'] = [ '#type' =>'link', '#title' => $this->t('Preview'), '#attributes' => [ 'class' => ['button', 'button--primary'], ], '#url' => $entity->toUrl('preview-page',[$entity->id()]) ]; > return $actions; > > 

add form

*/ public function buildHeader() < $header['label'] = $this->t('Label'); $header['id'] = $this->t('Machine name'); $header['status'] = $this->t('Status'); $header['color'] = $this->t('Color'); $header['point_value'] = $this->t('Points'); return $header + parent::buildHeader(); > /** * */ public function buildRow(EntityInterface $entity) < /** @var \Drupal\codimth_entity_config\BallInterface $entity */ $row['label'] = $entity->label(); $row['id'] = $entity->id(); $row['status'] = $entity->status() ? $this->t('Enabled') : $this->t('Disabled'); $row['color'] = $entity->getColor(); $row['point_value'] = $entity->getPointValue(); return $row + parent::buildRow($entity); > /** * */ public function getDefaultOperations(EntityInterface $entity) < $operations = parent::getDefaultOperations($entity); $operations['preview'] = array( 'title' =>t('Preview'), 'weight' => 20, 'url' => $this->ensureDestination($entity->toUrl('preview-page',[$entity->id()])), ); return $operations; > >

Creating a configuration entity type in Drupal 8

getStorage('ball') ->load($ball); $items = [ 'Label: ' => $entity->label(), $entity->id(), $entity->status(), $entity->get('description'), $entity->getColor(), $entity->getPointValue(), ]; return array( '#theme' => 'item_list', '#items' => $items, ); > >

For the Lazy

You can generate a custom config entity using Drush or Drupal Console.

Using Drush:

vendor/bin/drush generate module-configuration-entity 

Using Drupal Console:

vendor/bin/drupal generate:entity:config 

Next steps