Note: All plugin types provided by Drupal core support PHP attributes now in Drupal 11.2. For plugin types defined by contributed modules, consult the change records or release notes for the respective module. Ensure that
Convert plugins
- Add use statement for plugin specific attribute class (See Table below for conversion)
- (optional) Add use statement for TranslatableMarkup, if needed
- Convert annotations to attribute. Note the syntax changes, = becomes : for top-level attributes, arrays use regular PHP syntax, inner objects like TranslatableMarkup use new instead of @, class names can use ::class shorthand
Example:
Before
namespace Drupal\Core\Action\Plugin\Action;
use Drupal\Core\Session\AccountInterface;
/**
* Publishes an entity.
*
* @Action(
* id = "entity:publish_action",
* action_label = @Translation("Publish"),
* deriver = "Drupal\Core\Action\Plugin\Action\Derivative\EntityPublishedActionDeriver",
* )
*/
class PublishAction extends EntityActionBase {
After
namespace Drupal\Core\Action\Plugin\Action;
use Drupal\Core\Action\Plugin\Action\Derivative\EntityPublishedActionDeriver;
use Drupal\Core\Action\Attribute\Action;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
/**
* Publishes an entity.
*/
#[Action(
id: 'entity:publish_action',
action_label: new TranslatableMarkup('Publish'),
deriver: EntityPublishedActionDeriver::class
)]
class PublishAction extends EntityActionBase {
Backwards compatibility & edge cases with undefined traits
The plugin discovery supports that both annotations and attribute classes are defined on a plugin. Using a non-existing attribute class will not result in an error, so in earlier version of Drupal core or the respective contributed project, it will fall back to the annotation. The annotation can be removed once a sufficiently recent version of the module providing the plugin type is required.
Attribute discovery requires that the plugin class is loaded as a PHP file, which can result in problems if the plugin class relies on a base class, interface or specifically trait from a third module that may not be installed. Drupal core now provides a compatibility layer for these situations since #3502913: Add a fallback classloader that can handle missing traits for attribute discovery (Drupal 11.2) but consider defining the plugin dynamically in an alter hook to avoid those suppressed parsing errors.
Plugins converted from annotation to attributes in 10.2
| Annotation class | Attribute class |
\Drupal\Core\Annotation\Action |
\Drupal\Core\Action\Attribute\Action |
\Drupal\Core\Block\Annotation\Block |
\Drupal\Core\Block\Attribute\Block |
Plugins converted in other releases
Plugins converted from Annotations to Attributes in 10.3.0
Plugins converted from Annotations to Attributes in 11.1.0
Plugins converted from Annotations to Attributes in 11.2.0