Skip to main content
Category:

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/{ball}'
  defaults:
    _entity_form: 'ball.edit'
    _title: 'Edit a ball'
  requirements:
    _permission: 'administer ball'

entity.ball.delete_form:
  path: '/admin/structure/ball/{ball}/delete'
  defaults:
    _entity_form: 'ball.delete'
    _title: 'Delete a ball'
  requirements:
    _permission: 'administer ball'

entity.ball.preview_page:
  path: '/admin/structure/ball/{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.

<?php

namespace Drupal\codimth_entity_config\Entity;

use Drupal\Core\Config\Entity\ConfigEntityBase;
use Drupal\codimth_entity_config\BallInterface;

/**
 * Defines the ball entity type.
 *
 * @ConfigEntityType(
 *   id = "ball",
 *   label = @Translation("ball"),
 *   label_collection = @Translation("balls"),
 *   label_singular = @Translation("ball"),
 *   label_plural = @Translation("balls"),
 *   label_count = @PluralTranslation(
 *     singular = "@count ball",
 *     plural = "@count balls",
 *   ),
 *   handlers = {
 *     "list_builder" = "Drupal\codimth_entity_config\BallListBuilder",
 *     "form" = {
 *       "add" = "Drupal\codimth_entity_config\Form\BallForm",
 *       "edit" = "Drupal\codimth_entity_config\Form\BallForm",
 *       "delete" = "Drupal\Core\Entity\EntityDeleteForm"
 *     }
 *   },
 *   config_prefix = "ball",
 *   admin_permission = "administer ball",
 *   links = {
 *     "collection" = "/admin/structure/ball",
 *     "add-form" = "/admin/structure/ball/add",
 *     "preview-page" = "/admin/structure/ball/{ball}/preview",
 *     "edit-form" = "/admin/structure/ball/{ball}",
 *     "delete-form" = "/admin/structure/ball/{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;

    /**
     * {@inheritdoc}
     */
    public function getColor() {
        return $this->color;
    }

    /**
     * {@inheritdoc}
     */
    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.

<?php

namespace Drupal\codimth_entity_config;

use Drupal\Core\Config\Entity\ConfigEntityInterface;

/**
 * Provides an interface defining a ball entity type.
 */
interface BallInterface extends ConfigEntityInterface {
    public function getColor();
    public function getPointValue();
}

 

codimth_entity_config/src/Form/BallForm.php

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

<?php

namespace Drupal\codimth_entity_config\Form;

use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Form\FormStateInterface;

/**
 * ball form.
 *
 * @property \Drupal\codimth_entity_config\BallInterface $entity
 */
class BallForm extends EntityForm {

  /**
   * {@inheritdoc}
   */
  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;
  }

  /**
   * {@inheritdoc}
   */
  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;
  }


    /**
     * {@inheritdoc}
     */
    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

 

edit form

 

codimth_entity_config/src/BallListBuilder.php

this file to list all balls.

<?php

namespace Drupal\codimth_entity_config;

use Drupal\Core\Config\Entity\ConfigEntityListBuilder;
use Drupal\Core\Entity\EntityInterface;

/**
 * Provides a listing of balls.
 */
class BallListBuilder extends ConfigEntityListBuilder
{

    /**
     * {@inheritdoc}
     */
    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();
    }

    /**
     * {@inheritdoc}
     */
    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);
    }


    /**
     * {@inheritdoc}
     */
    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

 

codimth_entity_config/src/Controller/BallController.php

this file to preview a ball entity.

<?php

namespace Drupal\codimth_entity_config\Controller;

use Drupal\Core\Controller\ControllerBase;

class BallController extends ControllerBase
{
    public function preview($ball)
    {
        $entity = \Drupal::entityTypeManager()
            ->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

  • Clear your Drupal 8 caches. To do this I use this Drush command: drush cr if you don’t currently use Drush, I highly recommend using it, or the Drupal Console.
  • Now, go back to your site, and you should be able to see the new config entity you have just created.
  • I hope you found this article useful. let me know if you have any questions and I’ll be happy to answer them.
  • This code can be found and downloaded from https://github.com/codimth/codimth_entity_config.

 

Riadh Rahmi

Senior Web Developer PHP/Drupal & Laravel

I am a senior web developer, I have experience in planning and developing large scale dynamic web solutions especially in Drupal & Laravel.

Web Posts

Search

Page Facebook