Plugins Reference
Entity Builder uses three plugin types: Operations, Validators, and Extensions.
Plugin Types Overview
flowchart TB
subgraph Plugins["Entity Builder Plugins"]
OP[EbOperation<br/>Execute changes]
VAL[EbValidator<br/>Cross-cutting validation]
EXT[EbExtension<br/>Add YAML keys & operations]
end
subgraph Managers["Plugin Managers"]
OPM[plugin.manager.eb_operation]
VALM[plugin.manager.eb_validator]
EXTM[plugin.manager.eb_extension]
end
OP --> OPM
VAL --> VALM
EXT --> EXTM
EbOperation Plugins
Operations are the executable units that create, update, or delete Drupal entities.
Core Operations
Plugin ID
Label
Type
Description
create_bundle
Create Bundle
create
Creates content type, vocabulary, media type
update_bundle
Update Bundle
update
Updates bundle configuration
delete_bundle
Delete Bundle
delete
Deletes a bundle
create_field
Create Field
create
Creates field storage and instance
update_field
Update Field
update
Updates field configuration
delete_field
Delete Field
delete
Deletes field instance
hide_field
Hide Field
update
Hides field from display
reorder_fields
Reorder Fields
update
Changes field display order
configure_form_mode
Configure Form Mode
update
Configures widget settings
configure_view_mode
Configure View Mode
update
Configures formatter settings
create_menu
Create Menu
create
Creates custom menu
create_menu_link
Create Menu Link
create
Creates menu link
Extension Operations
Module
Plugin ID
Description
eb_field_group
create_field_group
Creates field group
eb_field_group
update_field_group
Updates field group
eb_field_group
delete_field_group
Deletes field group
eb_pathauto
create_pathauto_pattern
Creates URL pattern
eb_auto_entitylabel
configure_auto_entitylabel
Configures auto labels
Operation Attribute
#[ EbOperation (
id : 'my_operation' ,
label : new TranslatableMarkup ( 'My Operation' ),
description : new TranslatableMarkup ( 'Description' ),
operationType : 'create' , // create, update, delete
)]
Operation Interfaces
Interface
Methods
Purpose
OperationInterface
setData(), getData(), validate()
Base interface
FullOperationInterface
execute()
Executable operations
ReversibleOperationInterface
rollback()
Rollback support
PreviewableOperationInterface
preview()
Preview generation
Creating an Operation
<? php
namespace Drupal\my_module\Plugin\EbOperation ;
use Drupal\Core\StringTranslation\TranslatableMarkup ;
use Drupal\eb\Attribute\EbOperation ;
use Drupal\eb\PluginBase\OperationBase ;
use Drupal\eb\Result\ExecutionResult ;
use Drupal\eb\Result\PreviewResult ;
use Drupal\eb\Result\RollbackResult ;
use Drupal\eb\Result\ValidationResult ;
#[ EbOperation (
id : 'create_my_entity' ,
label : new TranslatableMarkup ( 'Create My Entity' ),
description : new TranslatableMarkup ( 'Creates a my entity' ),
operationType : 'create' ,
)]
class CreateMyEntityOperation extends OperationBase {
/**
* {@inheritdoc}
*/
public function validate () : ValidationResult {
$result = new ValidationResult ();
$this -> validateRequiredFields ([ 'entity_id' , 'label' ], $result );
return $result ;
}
/**
* {@inheritdoc}
*/
public function preview () : PreviewResult {
$preview = new PreviewResult ();
$preview -> addOperation (
'create' ,
'my_entity' ,
$this -> getDataValue ( 'entity_id' ),
$this -> t ( 'Create @label' , [ '@label' => $this -> getDataValue ( 'label' )])
);
return $preview ;
}
/**
* {@inheritdoc}
*/
public function execute () : ExecutionResult {
// Create the entity
$entity = $this -> entityTypeManager
-> getStorage ( 'my_entity' )
-> create ([
'id' => $this -> getDataValue ( 'entity_id' ),
'label' => $this -> getDataValue ( 'label' ),
]);
$entity -> save ();
$result = new ExecutionResult ( TRUE );
$result -> addMessage ( $this -> t ( 'Created @label' , [ '@label' => $entity -> label ()]));
$result -> setRollbackData ([ 'entity_id' => $entity -> id (), 'was_new' => TRUE ]);
return $result ;
}
/**
* {@inheritdoc}
*/
public function rollback () : RollbackResult {
$rollbackData = $this -> getDataValue ( '_rollback_data' , []);
$entityId = $rollbackData [ 'entity_id' ] ?? $this -> getDataValue ( 'entity_id' );
$entity = $this -> entityTypeManager -> getStorage ( 'my_entity' ) -> load ( $entityId );
if ( $entity && ( $rollbackData [ 'was_new' ] ?? FALSE )) {
$entity -> delete ();
}
$result = new RollbackResult ( TRUE );
$result -> addMessage ( $this -> t ( 'Deleted @id' , [ '@id' => $entityId ]));
return $result ;
}
}
EbValidator Plugins
Validators check cross-cutting concerns across all operations.
Core Validators
Plugin ID
Description
dependency_validator
Verifies entity/bundle/field existence
required_fields_validator
Checks required properties
unique_name_validator
Prevents naming conflicts
field_type_validator
Validates field type exists
widget_compatibility_validator
Checks widget-field compatibility
formatter_compatibility_validator
Checks formatter-field compatibility
circular_dependency_validator
Detects circular dependencies
Validator Attribute
#[ EbValidator (
id : 'my_validator' ,
label : new TranslatableMarkup ( 'My Validator' ),
description : new TranslatableMarkup ( 'Validates custom rules' ),
)]
Creating a Validator
<? php
namespace Drupal\my_module\Plugin\EbValidator ;
use Drupal\Core\StringTranslation\TranslatableMarkup ;
use Drupal\eb\Attribute\EbValidator ;
use Drupal\eb\PluginBase\ValidatorBase ;
use Drupal\eb\PluginInterfaces\OperationInterface ;
use Drupal\eb\Result\ValidationResult ;
#[ EbValidator (
id : 'naming_convention_validator' ,
label : new TranslatableMarkup ( 'Naming Convention Validator' ),
description : new TranslatableMarkup ( 'Enforces naming conventions' ),
)]
class NamingConventionValidator extends ValidatorBase {
/**
* {@inheritdoc}
*/
public function validate ( OperationInterface $operation , array $context = []) : ValidationResult {
$result = new ValidationResult ();
$operationType = $operation -> getDataValue ( 'operation' );
if ( $operationType === 'create_bundle' ) {
$bundleId = $operation -> getDataValue ( 'bundle_id' );
// Enforce prefix
if ( ! str_starts_with ( $bundleId , 'myapp_' )) {
$result -> addError (
'Bundle ID must start with "myapp_".' ,
'bundle_id' ,
'naming_convention'
);
}
}
return $result ;
}
}
EbExtension Plugins
Extensions add custom YAML keys, operations, and integration logic.
Core Extensions
Module
Plugin ID
YAML Keys
Operations
eb_field_group
field_group
field_group_definitions
create_field_group, etc.
eb_pathauto
pathauto
- (bundle column)
create_pathauto_pattern
eb_auto_entitylabel
auto_entitylabel
- (bundle columns)
configure_auto_entitylabel
Extension Attribute
#[ EbExtension (
id : 'my_extension' ,
label : new TranslatableMarkup ( 'My Extension' ),
description : new TranslatableMarkup ( 'Adds my functionality' ),
yaml_keys : [ 'my_definitions' ],
operations : [ 'create_my_entity' , 'update_my_entity' ],
module_dependencies : [ 'my_dependency' ],
)]
Extension Interface
Method
Purpose
buildOperations(array $data)
Convert YAML to operations
getOperationDependencies(array $operation, array $batch)
Declare dependencies
detectChanges(array $operation, array $context)
Change detection for sync mode
checkDependencies(array $operation)
Verify dependencies exist
appliesTo(array $operation)
Check if extension handles operation
getYamlKeys()
Get YAML keys from plugin definition
getOperations()
Get operations from plugin definition
extractConfig(string $entityType, string $bundle)
Export existing config
Creating an Extension
See the Creating Extensions guide for complete examples.
Plugin Discovery
List All Plugins
// Operations
$operationManager = \Drupal :: service ( 'plugin.manager.eb_operation' );
$definitions = $operationManager -> getDefinitions ();
// Validators
$validatorManager = \Drupal :: service ( 'plugin.manager.eb_validator' );
$definitions = $validatorManager -> getDefinitions ();
// Extensions
$extensionManager = \Drupal :: service ( 'plugin.manager.eb_extension' );
$extensions = $extensionManager -> getExtensions ();
Create Plugin Instance
// Create operation instance
$operation = $operationManager -> createInstance ( 'create_field' , [
'entity_type' => 'node' ,
'bundle' => 'article' ,
'field_name' => 'field_body' ,
'field_type' => 'text_long' ,
]);
// Create validator instance
$validator = $validatorManager -> createInstance ( 'dependency_validator' );
Extension Manager Methods
$extensionManager = \Drupal :: service ( 'plugin.manager.eb_extension' );
// Get extensions for operation type
$extensions = $extensionManager -> getExtensionsForOperation ( 'create_field_group' );
// Get extensions for YAML key
$extensions = $extensionManager -> getExtensionsForYamlKey ( 'field_group_definitions' );
// Get all definition keys from extensions
$keys = $extensionManager -> getAllDefinitionKeys ();
Plugin Namespace Locations
Plugin Type
Namespace
Directory
EbOperation
Drupal\{module}\Plugin\EbOperation
src/Plugin/EbOperation/
EbValidator
Drupal\{module}\Plugin\EbValidator
src/Plugin/EbValidator/
EbExtension
Drupal\{module}\Plugin\EbExtension
src/Plugin/EbExtension/
Best Practices
Use base classes - Extend OperationBase, ValidatorBase, EbExtensionBase
Implement all interfaces - Full operations need preview, execute, rollback
Store rollback data - Enable undo functionality
Handle exceptions - Use specific exception types with meaningful messages
Log operations - Use the logger channel for audit trail
Test thoroughly - Write unit tests for all plugin methods