Skip to main content

Why Drupal Plugins use Annotations / Attributes

Learn why you need to use PHP Annotations or Attributes in Drupal plugins.

#[Attributes]

Annotations are a programming construct that let developers add metadata to classes (and other things).

Drupal 8 introduced the requirement to use a specific annotation when declaring plugin blocks (programmed blocks, as opposed to content blocks created through Drupal's admin UI).

Example Block definition using an annotation:

Code

/**
 * Provides a 'Hello World' Block.
 *
 * @Block(
 *   id = 'hello_world_block',
 *   admin_label = 'Hello World Block',
 *   category = 'Hello World'
 * )
 */
class HelloWorldBlock extends BlockBase {
// ...
}

As PHP did not have any annotation syntax natively, Drupal chose the widely used Doctrine/Annotations library (part of the equally widely used Doctrine ORM) to let developers provide annotations as DocBlock comments.

Doctrine's implementation of annotations is an example of a userland implementation: something provided by a third-party library that adds new functionality or provides an alternative to existing, native functionality.

Fast forward about 10 years.

With PHP 8 came Attributes, a native implementation of annotations. As of Drupal 10.2, certain types of plugins started to support the Attribute syntax as well as the annotations syntax.

As we no longer need to rely on the third party Doctrine/Annotations library, Drupal annotations are being phased out in favour of PHP Attributes.

Example Block definition using a PHP Attribute:

Code

/**
 * Provides a 'Hello World' Block.
 */
#[Block(
  id: 'hello_world_block',
  admin_label: new TranslatableMarkup('Hello World Block'),
  category: new TranslatableMarkup('Hello World')
)]
class HelloWorldBlock extends BlockBase {
  // ...
}

Even Doctrine/ORM has abandoned its own annotations library and switched to the new native Attributes syntax.

Why use annotations / attributes?

Why did Drupal choose the annotation/attribute approach in the first place?

For a block plugin you need to provide its id through an annotation. But for a form plugin you must provide its id via getId() method.

Why two different approaches?

Discoverability and performance

Whenever Drupal needs to show a list of available blocks - such as on the Block Library admin page - it needs to get that information from somewhere.

If block plugins were regular classes without annotations, Drupal would have to instantiate each class just to learn its id and admin label, which takes up valuable memory and processor time.

If block plugin classes use an annotation/attribute, Drupal can simply scan code files in certain directories and retrieve the id/name/... metadata without having to instantiate those classes. This information is then cached for more performance gains.

However, there is no need to list all possible form plugins anywhere, so there was no performance-related reason for forms to switch to annotations / attributes.

And that's it. That's why some Drupal plugins use annotations / PHP Attributes.

Summary

  • Userland Annotations and native PHP Attributes let you add (configuration) metadata to classes (and other things).
  • As of Drupal 10.2 Annotations are phased out in favour of PHP Attributes.
  • In certain cases, such as for plugins, Drupal uses Annotations / Attributes for performance reasons.