On this page
Service Tags
About Service Tags
Tags are used to indicate that a service should be registered or used in some special way, or that it belongs to a category. See the Symfony documentation on service tags.
Drupal 10 and 11 note: Drupal tags are implemented on top of the Symfony container (Drupal 10 is based on Symfony 6.2; Drupal 11 is based on Symfony 7). Tags are processed when Drupal compiles the container, so changes to tags take effect after a container rebuild, not instantly at runtime.
The Service Tags API page documents Drupal core service tags and their supported attributes (for example priority, id, and tag-specific keys).
Help document the service tags.
Collecting Services
Guidance: When you want a module to offer an extension point, prefer a tag-based pattern (service collectors, tagged iterators, or event subscribers) over swapping existing services. This keeps multiple implementations compatible and makes ordering explicit via priority.
Drupal has an API for defining a service collector, which is a special type of service that collects other services by tag (these are called the collected services). The way service collectors work is that you define the service collector and one or more collected services (define their classes and the *.services.yml definition). When the collector service is used, Drupal will instantiate it (as it does for any other service, using dependency injection), and then locate the collected services, instantiate them, and pass their instances to a method on the collector service class for processing.
One example is the string_translation service. The exact definition may vary slightly between core releases, but the pattern is consistent:
# core.services.yml:
string_translation:
class: Drupal\Core\StringTranslation\TranslationManager
arguments: ['@language.default']
tags:
- { name: service_collector, tag: string_translator, call: addTranslator }
As you can see in this example, the service definition has a tag whose name is service_collector, which is how to tell Drupal that a service is a service collector. The tag attribute on the tag definition tells what tag name the collected services need to be tagged with in order to be collected; this can be omitted to use the collecting service's ID as the tag name.
The call attribute on the tag tells Drupal that the TranslationManager::addTranslator() method should be called once for each collected service that is located. Here's the method code:
// \Drupal\Core\StringTranslation\TranslationManager:
public function addTranslator(TranslatorInterface $translator, $priority = 0) {
$this->translators[$priority][] = $translator;
// Reset sorted translators property to trigger rebuild.
$this->sortedTranslators = NULL;
return $this;
}
The collecting method receives the collected service as its first parameter. In addition, if the collecting service's method signature contains parameters named id (the collected service's ID) or priority (the collected service's configured priority), the compiler pass that performs the collecting work during container compilation (TaggedHandlersPass) will ensure that these attributes will be taken from the collected service's service definition and passed into the method.
Here's an example of a service that will be collected by the previously-shown string_translation service:
# core.services.yml:
string_translator.custom_strings:
class: Drupal\Core\StringTranslation\Translator\CustomStrings
arguments: ['@settings']
tags:
- { name: string_translator, priority: 30 }
As you can see, this service is tagged string_translator, which is what causes it to be collected into the string_translation service. If priority is omitted, it is treated as 0. Also, since the tag has a priority attribute, this value (30) and an instance of the CustomStrings class will be passed into TranslationManager::addTranslator() when services are collected. A higher priority service will be used before a lower priority one. Many core services use a priority of 0, but some core modules use higher priorities.
Help improve this page
You can:
- Log in, click Edit, and edit this page
- Log in, click Discuss, update the Page status value, and suggest an improvement
- Log in and create a Documentation issue with your suggestion