Introduction
PHP gets better over time, and one recent improvement is PHP attributes, which came with PHP 8. These attributes help organize things like classes, methods, and properties by adding extra information. This makes it easier for tools and frameworks to understand and work with the code. In this post, we'll look into PHP attributes, comparing them to Drupal annotations, talking about their advantages, and showing examples. Plus, we'll show you how easily attributes fit into Drupal.
Drupal Plugin Discovery mechanism:
In Drupal, the Plugin Discovery thing finds and adds plugins as needed. Plugins are like building blocks that help add new features to Drupal. The Plugin API is like a helpful tool that makes it easy to include these plugins in different parts of the system, like blocks and fields.
Annotations: Drupal plugins often use annotations for discovery. Annotations are special comments in PHP code that provide metadata about the class.
YAML Files: Some plugins are discovered through YAML files, where plugin definitions are specified in a structured format.
Annotations in Drupal
Drupal's plugin system, a robust and flexible component, heavily relies on annotations for various purposes. These annotations, often expressed as PHPDoc comments, convey metadata information to the system. Here's an example of an annotation:
Let's compare examples of annotations and attributes for a simple class definition:
Example of Annotations:
Example of Attributes:
In the attributes example, we see a more concise and integrated syntax for expressing metadata.
Why Use Attributes Instead of Annotations?
Several reasons make PHP attributes a compelling choice over annotations, even in Drupal development:
- Drupal currently utilizes the "doctrine/annotations" library for parsing annotations (https://github.com/doctrine/annotations). Attributes, which are a native feature of the PHP language, are employed, eliminating the necessity for parsing docblocks. This approach leads to code that is cleaner and more easily readable.
- The great thing about being able to create instances of objects in attributes is that we're not using attributes for this. We're using exactly the same objects as you would in regular PHP code. So for translatable strings that's \Drupal\Core\StringTranslation\TranslatableMarkup(). That means the way these strings are translated is exactly the same as regular PHP code. We've got rid a whole abstraction layer (i.e. \Drupal\Core\Annotation\Translation) and that's fantastic.
- The attributes language feature was added to php to do the kind of things we (and doctrine ORM) are using doctrine annotations for. It is therefore reasonable that doctrine annotations will be deprecated in the future.
- With Attributes finally we might be able to get IDE autocompletion and some amount of control and discoverability over the entity type annotations. Since attributes are part of the language, IDEs can provide better autocompletion and code navigation support. Developers can explore and use attributes more efficiently within their integrated development environment.
Example of Using Attributes in Drupal
Drupal is using something new called PHP attributes, and modules are beginning to use this cool feature.
Let us understand the process of creating a custom plugin type using Attribute and Annotation discovery mechanisms through the following example:
Plugins have several parts, in the example below we will cover only those aspects which are relevant for understanding the plugins discovery mechanism :
1. Plugin Definition
The first step is to define the definition for your plugin.
Annotation Definition:
This is a simple class that extends Drupal\Component\Annotation\Plugin to define the variables
you want listed in the annotation comments of the plugin. This file goes in [your_module]/src/Annotation, and file name and class name match. for example: Importer.php
Attribute Definition:
This extends Drupal\Component\Plugin\Attribute\Plugin class. The Attribute definition will go into the folder [your_module]/src/Attribute and
as always the file name and class name match. for example: Importer.php.
Similar to annotation the variables defined here are used while using Attribute discovery for your plugin type.
2. Plugin manager
Responsible for discovering and loading plugins, the most important part in any plugin type is the manager.This file resides inside the "[example_module]/src" folder mostly with a name ending with Manager.php.
We have the file ImporterPluginManager.php
This single file is responsible for discovering our "Importer" plugins of which are either using Annotation or Attribute based discovery mechanism.
Here the important line is
because we are supporting both (Annotation and Attribute discovery)Importer::class is used to discover plugins using "Attribute" discovery Drupal\example_plugin\Attribute\Importer;whereas 'Drupal\example_plugin\Annotation\Importer' is used for the plugins using traditional Annotation discovery
To remove support for either of the discovery mechanisms for your custom plugin type you can remove one of the parameters:Importer::class or 'Drupal\example_plugin\Annotation\Importer'
3. Implementation of plugin of type plugin_name (in this example plugin_name is “Importer”)
Now assume we have created all the required files for defining a custom plugin type let us see examples of the same plugin typewith one using Annotation and other one using Attribute discover
within the "[example_module]/src/Plugin" folder we can have one plugin for example JSONImporter.php using Annotation discover
While CSVImporter.php using Attribute discover mechanism
Complete code of the above example could be found on https://github.com/prashantdsala/example_plugin
Drupal Change record:
Plugin types should use PHP attributes instead of annotations
Plugin implementations should use PHP attributes instead of annotations
Plugin types are still being converted to Attribute Discovery. At the time of writing this blog post, only two of the plugin types support Attribute discovery which as mentioned below:
Conclusion
PHP attributes are like new tools that make the PHP language better. They help make the code cleaner, easier to read. In Drupal, using these new tools instead of the old way brings a bunch of benefits. It makes the code work better with the system, fits well with code editors, and makes the code more reliable. As PHP gets updated, using these tools in Drupal is a good idea. It helps keep the code up-to-date and in line with the newest features of the language.