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;
}
}
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;
}
}
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:
|
Using Drupal Console:
|
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.