Change record status: 
Project: 
Introduced in branch: 
11.5.x
Introduced in version: 
11.5.0
Description: 

Previously, plugin definitions were configured via a single attribute, provided by the module that defines the plugin type. A module could not add additional properties to a plugin type it does not own.

Attributes that implement Drupal\Component\Plugin\Attribute\PluginPropertyInterface can now be placed on a plugin class, next to the plugin definition attribute. Plugin discovery applies them when the module that provides the attribute class is installed. It ignores them when that module is not installed.

Example attribute:

namespace Drupal\my_module\Attribute;

use Drupal\Component\Plugin\Attribute\PluginPropertyInterface;

#[\Attribute(\Attribute::TARGET_CLASS)]
class MyModuleProperty implements PluginPropertyInterface {

  public function __construct(
    public readonly string $value,
  ) {}

  public function addToDefinition(string $id, array|object $definition): array|object {
    $definition['my_module_property'] = $this->value;
    return $definition;
  }

}

When a plugin definition is an object, addToDefinition() must call the setter on that object instead of setting an array key.

Add \Attribute::IS_REPEATABLE to the flags if it makes sense for the attribute to be used more than once.

Then use the attribute on a plugin class definition:

use Drupal\my_module\Attribute\MyModuleProperty;

#[Block(
  id: 'example',
  admin_label: new TranslatableMarkup('Example'),
)]
#[MyModuleProperty('some value')]
class ExampleBlock extends BlockBase {}

When my_module is installed, the example block plugin definition will have the my_module_property key set to some value.

Note that using these attributes to set plugin definition properties to values that have module dependencies may cause fatal errors during plugin discovery. Using the attribute to set a value that is an enum, object, or constant provided by a module that is not installed should be avoided. The ideal use case is to set property values to either scalars or arrays, or objects from classes provided by Drupal\Core, such as TranslatableMarkup.

Impacts: 
Module developers