Skip to content
  • About
    • What is Symfony?
    • Community
    • News
    • Contributing
    • Support
  • Documentation
    • Symfony Docs
    • Symfony Book
    • Screencasts
    • Symfony Bundles
    • Symfony Cloud
    • Training
  • Services
    • SensioLabs Professional services to help you with Symfony
    • Platform.sh for Symfony Best platform to deploy Symfony apps
    • SymfonyInsight Automatic quality checks for your apps
    • Symfony Certification Prove your knowledge and boost your career
    • Blackfire Profile and monitor performance of your apps
  • Other
  • Blog
  • Download
sponsored by SensioLabs
  1. Home
  2. Documentation
  3. Reference
  4. Built-in Symfony Service Tags
  • Documentation
  • Book
  • Reference
  • Bundles
  • Cloud

Table of Contents

  • auto_alias
  • console.command
  • controller.argument_value_resolver
  • data_collector
  • doctrine.event_listener
  • doctrine.event_subscriber
  • form.type
  • form.type_extension
  • form.type_guesser
  • kernel.cache_clearer
  • kernel.cache_warmer
  • kernel.event_listener
    • Core Event Listener Reference
  • kernel.event_subscriber
  • kernel.fragment_renderer
  • monolog.logger
  • monolog.processor
  • routing.loader
  • routing.expression_language_provider
  • security.expression_language_provider
  • security.remember_me_aware
  • security.voter
  • serializer.encoder
  • serializer.normalizer
  • swiftmailer.default.plugin
  • templating.helper
  • translation.loader
  • translation.extractor
  • translation.dumper
  • twig.extension
  • twig.loader
  • twig.runtime
  • validator.constraint_validator
  • validator.initializer

Built-in Symfony Service Tags

Edit this page

Warning: You are browsing the documentation for Symfony 4.1, which is no longer maintained.

Read the updated version of this page for Symfony 6.2 (the current stable version).

Built-in Symfony Service Tags

Service tags are the mechanism used by the DependencyInjection component to flag services that require special processing, like console commands or Twig extensions.

These are the most common tags provided by Symfony components, but in your application there could be more tags available provided by third-party bundles:

Tag Name Usage
auto_alias Define aliases based on the value of container parameters
console.command Add a command
controller.argument_value_resolver Register a value resolver for controller arguments such as Request
data_collector Create a class that collects custom data for the profiler
doctrine.event_listener Add a Doctrine event listener
doctrine.event_subscriber Add a Doctrine event subscriber
form.type Create a custom form field type
form.type_extension Create a custom "form extension"
form.type_guesser Add your own logic for "form type guessing"
kernel.cache_clearer Register your service to be called during the cache clearing process
kernel.cache_warmer Register your service to be called during the cache warming process
kernel.event_listener Listen to different events/hooks in Symfony
kernel.event_subscriber To subscribe to a set of different events/hooks in Symfony
kernel.fragment_renderer Add new HTTP content rendering strategies
monolog.logger Logging with a custom logging channel
monolog.processor Add a custom processor for logging
routing.loader Register a custom service that loads routes
routing.expression_language_provider Register a provider for expression language functions in routing
security.expression_language_provider Register a provider for expression language functions in security
security.voter Add a custom voter to Symfony's authorization logic
security.remember_me_aware To allow remember me authentication
serializer.encoder Register a new encoder in the serializer service
serializer.normalizer Register a new normalizer in the serializer service
swiftmailer.default.plugin Register a custom SwiftMailer Plugin
templating.helper Make your service available in PHP templates
translation.loader Register a custom service that loads translations
translation.extractor Register a custom service that extracts translation messages from a file
translation.dumper Register a custom service that dumps translation messages
twig.extension Register a custom Twig Extension
twig.loader Register a custom service that loads Twig templates
twig.runtime Register a lazy-loaded Twig Extension
validator.constraint_validator Create your own custom validation constraint
validator.initializer Register a service that initializes objects before validation

auto_alias

Purpose: Define aliases based on the value of container parameters

Consider the following configuration that defines three different but related services:

  • YAML
  • XML
  • PHP
1
2
3
4
5
6
7
8
9
10
services:
    app.mysql_lock:
        class: App\Lock\MysqlLock
        public: false
    app.postgresql_lock:
        class: App\Lock\PostgresqlLock
        public: false
    app.sqlite_lock:
        class: App\Lock\SqliteLock
        public: false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>
        <service id="app.mysql_lock" public="false"
                 class="App\Lock\MysqlLock" />
        <service id="app.postgresql_lock" public="false"
                 class="App\Lock\PostgresqlLock" />
        <service id="app.sqlite_lock" public="false"
                 class="App\Lock\SqliteLock" />
    </services>
</container>
1
2
3
4
5
6
7
use App\Lock\MysqlLock;
use App\Lock\PostgresqlLock;
use App\Lock\SqliteLock;

$container->register('app.mysql_lock', MysqlLock::class)->setPublic(false);
$container->register('app.postgresql_lock', PostgresqlLock::class)->setPublic(false);
$container->register('app.sqlite_lock', SqliteLock::class)->setPublic(false);

Instead of dealing with these three services, your application needs a generic app.lock service that will be an alias to one of these services, depending on some configuration. Thanks to the auto_alias option, you can automatically create that alias based on the value of a configuration parameter.

Considering that a configuration parameter called database_type exists. Then, the generic app.lock service can be defined as follows:

  • YAML
  • XML
  • PHP
1
2
3
4
5
6
7
8
9
10
services:
    app.mysql_lock:
        # ...
    app.postgresql_lock:
        # ...
    app.sqlite_lock:
        # ...
    app.lock:
        tags:
            - { name: auto_alias, format: "app.%database_type%_lock" }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>
        <service id="app.mysql_lock" public="false"
                 class="App\Lock\MysqlLock" />
        <service id="app.postgresql_lock" public="false"
                 class="App\Lock\PostgresqlLock" />
        <service id="app.sqlite_lock" public="false"
                 class="App\Lock\SqliteLock" />

        <service id="app.lock">
            <tag name="auto_alias" format="app.%database_type%_lock" />
        </service>
    </services>
</container>
1
2
3
4
5
6
7
8
9
10
use App\Lock\MysqlLock;
use App\Lock\PostgresqlLock;
use App\Lock\SqliteLock;

$container->register('app.mysql_lock', MysqlLock::class)->setPublic(false);
$container->register('app.postgresql_lock', PostgresqlLock::class)->setPublic(false);
$container->register('app.sqlite_lock', SqliteLock::class)->setPublic(false);

$container->register('app.lock')
    ->addTag('auto_alias', ['format' => 'app.%database_type%_lock']);

The format option defines the expression used to construct the name of the service to alias. This expression can use any container parameter (as usual, wrapping their names with % characters).

Note

When using the auto_alias tag, it's not mandatory to define the aliased services as private. However, doing that (like in the above example) makes sense most of the times to prevent accessing those services directly instead of using the generic service alias.

Note

You need to manually add the Symfony\Component\DependencyInjection\Compiler\AutoAliasServicePass compiler pass to the container for this feature to work.

console.command

Purpose: Add a command to the application

For details on registering your own commands in the service container, read How to Define Commands as Services.

controller.argument_value_resolver

Purpose: Register a value resolver for controller arguments such as Request

Value resolvers implement the ArgumentValueResolverInterface and are used to resolve argument values for controllers as described here: Extending Action Argument Resolving.

data_collector

Purpose: Create a class that collects custom data for the profiler

For details on creating your own custom data collection, read the How to Create a custom Data Collector article.

doctrine.event_listener

Purpose: Add a Doctrine event listener

For details on creating Doctrine event listeners, read the Doctrine Event Listeners and Subscribers article.

doctrine.event_subscriber

Purpose: Add a Doctrine event subscriber

For details on creating Doctrine event subscribers, read the Doctrine Event Listeners and Subscribers article.

form.type

Purpose: Create a custom form field type

For details on creating your own custom form type, read the How to Create a Custom Form Field Type article.

form.type_extension

Purpose: Create a custom "form extension"

For details on creating Form type extensions, read the How to Create a Form Type Extension article.

form.type_guesser

Purpose: Add your own logic for "form type guessing"

This tag allows you to add your own logic to the form guessing process. By default, form guessing is done by "guessers" based on the validation metadata and Doctrine metadata (if you're using Doctrine) or Propel metadata (if you're using Propel).

See also

For information on how to create your own type guesser, see Creating a custom Type Guesser.

kernel.cache_clearer

Purpose: Register your service to be called during the cache clearing process

Cache clearing occurs whenever you call cache:clear command. If your bundle caches files, you should add custom cache clearer for clearing those files during the cache clearing process.

In order to register your custom cache clearer, first you must create a service class:

1
2
3
4
5
6
7
8
9
10
11
12
// src/Cache/MyClearer.php
namespace App\Cache;

use Symfony\Component\HttpKernel\CacheClearer\CacheClearerInterface;

class MyClearer implements CacheClearerInterface
{
    public function clear($cacheDirectory)
    {
        // clear your cache
    }
}

If you're using the default services.yaml configuration, your service will be automatically tagged with kernel.cache_clearer. But, you can also register it manually:

  • YAML
  • XML
  • PHP
1
2
3
services:
    App\Cache\MyClearer:
        tags: [kernel.cache_clearer]
1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>
        <service id="App\Cache\MyClearer">
            <tag name="kernel.cache_clearer" />
        </service>
    </services>
</container>
1
2
3
4
5
6
use App\Cache\MyClearer;

$container
    ->register(MyClearer::class)
    ->addTag('kernel.cache_clearer')
;

kernel.cache_warmer

Purpose: Register your service to be called during the cache warming process

Cache warming occurs whenever you run the cache:warmup or cache:clear command (unless you pass --no-warmup to cache:clear). It is also run when handling the request, if it wasn't done by one of the commands yet.

The purpose is to initialize any cache that will be needed by the application and prevent the first user from any significant "cache hit" where the cache is generated dynamically.

To register your own cache warmer, first create a service that implements the CacheWarmerInterface interface:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// src/Cache/MyCustomWarmer.php
namespace App\Cache;

use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;

class MyCustomWarmer implements CacheWarmerInterface
{
    public function warmUp($cacheDirectory)
    {
        // ... do some sort of operations to "warm" your cache
    }

    public function isOptional()
    {
        return true;
    }
}

The isOptional() method should return true if it's possible to use the application without calling this cache warmer. In Symfony, optional warmers are always executed by default (you can change this by using the --no-optional-warmers option when executing the command).

If you're using the default services.yaml configuration, your service will be automatically tagged with kernel.cache_warmer. But, you can also register it manually:

  • YAML
  • XML
  • PHP
1
2
3
4
services:
    App\Cache\MyCustomWarmer:
        tags:
            - { name: kernel.cache_warmer, priority: 0 }
1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>
        <service id="App\Cache\MyCustomWarmer">
            <tag name="kernel.cache_warmer" priority="0" />
        </service>
    </services>
</container>
1
2
3
4
5
6
use App\Cache\MyCustomWarmer;

$container
    ->register(MyCustomWarmer::class)
    ->addTag('kernel.cache_warmer', ['priority' => 0])
;

Note

The priority is optional and its value is a positive or negative integer that defaults to 0. The higher the number, the earlier that warmers are executed.

Caution

If your cache warmer fails its execution because of any exception, Symfony won't try to execute it again for the next requests. Therefore, your application and/or bundles should be prepared for when the contents generated by the cache warmer are not available.

In addition to your own cache warmers, Symfony components and third-party bundles define cache warmers too for their own purposes. You can list them all with the following command:

1
$ php bin/console debug:container --tag=kernel.cache_warmer

kernel.event_listener

Purpose: To listen to different events/hooks in Symfony

During the execution of a Symfony application, different events are triggered and you can also dispatch custom events. This tag allows you to hook your own classes into any of those events.

For a full example of this listener, read the Events and Event Listeners article.

Core Event Listener Reference

For the reference of Event Listeners associated with each kernel event, see the Symfony Events Reference.

kernel.event_subscriber

Purpose: To subscribe to a set of different events/hooks in Symfony

This is an alternative way to create an event listener, and is the recommended way (instead of using kernel.event_listener). See Events and Event Listeners.

kernel.fragment_renderer

Purpose: Add a new HTTP content rendering strategy

To add a new rendering strategy - in addition to the core strategies like EsiFragmentRenderer - create a class that implements FragmentRendererInterface, register it as a service, then tag it with kernel.fragment_renderer.

monolog.logger

Purpose: To use a custom logging channel with Monolog

Monolog allows you to share its handlers between several logging channels. The logger service uses the channel app but you can change the channel when injecting the logger in a service.

  • YAML
  • XML
  • PHP
1
2
3
4
5
services:
    App\Log\CustomLogger:
        arguments: ['@logger']
        tags:
            - { name: monolog.logger, channel: app }
1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>
        <service id="App\Log\CustomLogger">
            <argument type="service" id="logger" />
            <tag name="monolog.logger" channel="app" />
        </service>
    </services>
</container>
1
2
3
4
5
6
use App\Log\CustomLogger;
use Symfony\Component\DependencyInjection\Reference;

$container->register(CustomLogger::class)
    ->addArgument(new Reference('logger'))
    ->addTag('monolog.logger', ['channel' => 'app']);

Tip

You can also configure custom channels in the configuration and retrieve the corresponding logger service from the service container directly (see How to Log Messages to different Files).

monolog.processor

Purpose: Add a custom processor for logging

Monolog allows you to add processors in the logger or in the handlers to add extra data in the records. A processor receives the record as an argument and must return it after adding some extra data in the extra attribute of the record.

The built-in IntrospectionProcessor can be used to add the file, the line, the class and the method where the logger was triggered.

You can add a processor globally:

  • YAML
  • XML
  • PHP
1
2
3
services:
    Monolog\Processor\IntrospectionProcessor:
        tags: [monolog.processor]
1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>
        <service id="Monolog\Processor\IntrospectionProcessor">
            <tag name="monolog.processor" />
        </service>
    </services>
</container>
1
2
3
4
5
6
use Monolog\Processor\IntrospectionProcessor;

$container
    ->register(IntrospectionProcessor::class)
    ->addTag('monolog.processor')
;

Tip

If your service is not a callable (using __invoke()) you can add the method attribute in the tag to use a specific method.

You can add also a processor for a specific handler by using the handler attribute:

  • YAML
  • XML
  • PHP
1
2
3
4
services:
    Monolog\Processor\IntrospectionProcessor:
        tags:
            - { name: monolog.processor, handler: firephp }
1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>
        <service id="Monolog\Processor\IntrospectionProcessor">
            <tag name="monolog.processor" handler="firephp" />
        </service>
    </services>
</container>
1
2
3
4
5
6
use Monolog\Processor\IntrospectionProcessor;

$container
    ->register(IntrospectionProcessor::class)
    ->addTag('monolog.processor', ['handler' => 'firephp'])
;

You can also add a processor for a specific logging channel by using the channel attribute. This will register the processor only for the security logging channel used in the Security component:

  • YAML
  • XML
  • PHP
1
2
3
4
services:
    Monolog\Processor\IntrospectionProcessor:
        tags:
            - { name: monolog.processor, channel: security }
1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>
        <service id="Monolog\Processor\IntrospectionProcessor">
            <tag name="monolog.processor" channel="security" />
        </service>
    </services>
</container>
1
2
3
4
5
6
use Monolog\Processor\IntrospectionProcessor;

$container
    ->register(IntrospectionProcessor::class)
    ->addTag('monolog.processor', ['channel' => 'security'])
;

Note

You cannot use both the handler and channel attributes for the same tag as handlers are shared between all channels.

routing.loader

Purpose: Register a custom service that loads routes

To enable a custom routing loader, add it as a regular service in one of your configuration and tag it with routing.loader:

  • YAML
  • XML
  • PHP
1
2
3
services:
    App\Routing\CustomLoader:
        tags: [routing.loader]
1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>
        <service id="App\Routing\CustomLoader">
            <tag name="routing.loader" />
        </service>
    </services>
</container>
1
2
3
4
5
6
use App\Routing\CustomLoader;

$container
    ->register(CustomLoader::class)
    ->addTag('routing.loader')
;

For more information, see How to Create a custom Route Loader.

routing.expression_language_provider

Purpose: Register a provider for expression language functions in routing

This tag is used to automatically register expression function providers for the routing expression component. Using these providers, you can add custom functions to the routing expression language.

security.expression_language_provider

Purpose: Register a provider for expression language functions in security

This tag is used to automatically register expression function providers for the security expression component. Using these providers, you can add custom functions to the security expression language.

security.remember_me_aware

Purpose: To allow remember me authentication

This tag is used internally to allow remember-me authentication to work. If you have a custom authentication method where a user can be remember-me authenticated, then you may need to use this tag.

If your custom authentication factory extends AbstractFactory and your custom authentication listener extends AbstractAuthenticationListener, then your custom authentication listener will automatically have this tag applied and it will function automatically.

security.voter

Purpose: To add a custom voter to Symfony's authorization logic

When you call isGranted() on Symfony's authorization checker, a system of "voters" is used behind the scenes to determine if the user should have access. The security.voter tag allows you to add your own custom voter to that system.

For more information, read the How to Use Voters to Check User Permissions article.

serializer.encoder

Purpose: Register a new encoder in the serializer service

The class that's tagged should implement the EncoderInterface and DecoderInterface.

For more details, see How to Use the Serializer.

serializer.normalizer

Purpose: Register a new normalizer in the Serializer service

The class that's tagged should implement the NormalizerInterface and DenormalizerInterface.

For more details, see How to Use the Serializer.

The priorities of the default normalizers can be found in the registerSerializerConfiguration() method.

swiftmailer.default.plugin

Purpose: Register a custom SwiftMailer Plugin

If you're using a custom SwiftMailer plugin (or want to create one), you can register it with SwiftMailer by creating a service for your plugin and tagging it with swiftmailer.default.plugin (it has no options).

Note

default in this tag is the name of the mailer. If you have multiple mailers configured or have changed the default mailer name for some reason, you should change it to the name of your mailer in order to use this tag.

A SwiftMailer plugin must implement the Swift_Events_EventListener interface. For more information on plugins, see SwiftMailer's Plugin Documentation.

Several SwiftMailer plugins are core to Symfony and can be activated via different configuration. For details, see Mailer Configuration Reference (SwiftmailerBundle).

templating.helper

Purpose: Make your service available in PHP templates

To enable a custom template helper, add it as a regular service in one of your configuration, tag it with templating.helper and define an alias attribute (the helper will be accessible via this alias in the templates):

  • YAML
  • XML
  • PHP
1
2
3
4
services:
    App\Templating\AppHelper:
        tags:
            - { name: templating.helper, alias: alias_name }
1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>
        <service id="App\Templating\AppHelper">
            <tag name="templating.helper" alias="alias_name" />
        </service>
    </services>
</container>
1
2
3
4
5
use App\Templating\AppHelper;

$container->register(AppHelper::class)
    ->addTag('templating.helper', ['alias' => 'alias_name'])
;

translation.loader

Purpose: To register a custom service that loads translations

By default, translations are loaded from the filesystem in a variety of different formats (YAML, XLIFF, PHP, etc).

See also

Learn how to load custom formats in the components section.

Now, register your loader as a service and tag it with translation.loader:

  • YAML
  • XML
  • PHP
1
2
3
4
services:
    App\Translation\MyCustomLoader:
        tags:
            - { name: translation.loader, alias: bin }
1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>
        <service id="App\Translation\MyCustomLoader">
            <tag name="translation.loader" alias="bin" />
        </service>
    </services>
</container>
1
2
3
4
5
6
use App\Translation\MyCustomLoader;

$container
    ->register(MyCustomLoader::class)
    ->addTag('translation.loader', ['alias' => 'bin'])
;

The alias option is required and very important: it defines the file "suffix" that will be used for the resource files that use this loader. For example, suppose you have some custom bin format that you need to load. If you have a bin file that contains French translations for the messages domain, then you might have a file translations/messages.fr.bin.

When Symfony tries to load the bin file, it passes the path to your custom loader as the $resource argument. You can then perform any logic you need on that file in order to load your translations.

If you're loading translations from a database, you'll still need a resource file, but it might either be blank or contain a little bit of information about loading those resources from the database. The file is key to trigger the load() method on your custom loader.

translation.extractor

Purpose: To register a custom service that extracts messages from a file

When executing the translation:update command, it uses extractors to extract translation messages from a file. By default, the Symfony Framework has a TwigExtractor and a PhpExtractor, which help to find and extract translation keys from Twig templates and PHP files.

You can create your own extractor by creating a class that implements ExtractorInterface and tagging the service with translation.extractor. The tag has one required option: alias, which defines the name of the extractor:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// src/Acme/DemoBundle/Translation/FooExtractor.php
namespace Acme\DemoBundle\Translation;

use Symfony\Component\Translation\Extractor\ExtractorInterface;
use Symfony\Component\Translation\MessageCatalogue;

class FooExtractor implements ExtractorInterface
{
    protected $prefix;

    /**
     * Extracts translation messages from a template directory to the catalogue.
     */
    public function extract($directory, MessageCatalogue $catalogue)
    {
        // ...
    }

    /**
     * Sets the prefix that should be used for new found messages.
     */
    public function setPrefix($prefix)
    {
        $this->prefix = $prefix;
    }
}
  • YAML
  • XML
  • PHP
1
2
3
4
services:
    App\Translation\CustomExtractor:
        tags:
            - { name: translation.extractor, alias: foo }
1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>
        <service id="App\Translation\CustomExtractor">
            <tag name="translation.extractor" alias="foo" />
        </service>
    </services>
</container>
1
2
3
4
use App\Translation\CustomExtractor;

$container->register(CustomExtractor::class)
    ->addTag('translation.extractor', ['alias' => 'foo']);

translation.dumper

Purpose: To register a custom service that dumps messages to a file

After a translation extractor has extracted all messages from the templates, the dumpers are executed to dump the messages to a translation file in a specific format.

Symfony already comes with many dumpers:

  • CsvFileDumper
  • IcuResFileDumper
  • IniFileDumper
  • MoFileDumper
  • PoFileDumper
  • QtFileDumper
  • XliffFileDumper
  • YamlFileDumper

You can create your own dumper by extending FileDumper or implementing DumperInterface and tagging the service with translation.dumper. The tag has one option: alias This is the name that's used to determine which dumper should be used.

  • YAML
  • XML
  • PHP
1
2
3
4
services:
    App\Translation\JsonFileDumper:
        tags:
            - { name: translation.dumper, alias: json }
1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>
        <service id="App\Translation\JsonFileDumper">
            <tag name="translation.dumper" alias="json" />
        </service>
    </services>
</container>
1
2
3
4
use App\Translation\JsonFileDumper;

$container->register(JsonFileDumper::class)
    ->addTag('translation.dumper', ['alias' => 'json']);

See also

Learn how to dump to custom formats in the components section.

twig.extension

Purpose: To register a custom Twig Extension

To enable a Twig extension, add it as a regular service in one of your configuration and tag it with twig.extension. If you're using the default services.yaml configuration, the service is auto-registered and auto-tagged. But, you can also register it manually:

  • YAML
  • XML
  • PHP
1
2
3
4
5
6
7
8
9
services:
    App\Twig\AppExtension:
        tags: [twig.extension]

    # optionally you can define the priority of the extension (default = 0).
    # Extensions with higher priorities are registered earlier. This is mostly
    # useful to register late extensions that override other extensions.
    App\Twig\AnotherExtension:
        tags: [{ name: twig.extension, priority: -100 }]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>
        <service id="App\Twig\AppExtension">
            <tag name="twig.extension" />
        </service>

        <service id="App\Twig\AnotherExtension">
            <tag name="twig.extension" priority="-100" />
        </service>
    </services>
</container>
1
2
3
4
5
6
7
8
9
10
11
use App\Twig\AppExtension;
use App\Twig\AnotherExtension;

$container
    ->register(AppExtension::class)
    ->addTag('twig.extension')
;
$container
    ->register(AnotherExtension::class)
    ->addTag('twig.extension', ['priority' => -100])
;

4.1

The priority attribute of the twig.extension tag was introduced in Symfony 4.1.

For information on how to create the actual Twig Extension class, see Twig's documentation on the topic or read the How to Write a custom Twig Extension article.

Before writing your own extensions, have a look at the Twig official extension repository which already includes several useful extensions. For example Intl and its localizeddate filter that formats a date according to user's locale. These official Twig extensions also have to be added as regular services:

  • YAML
  • XML
  • PHP
1
2
3
services:
    Twig\Extensions\IntlExtension:
        tags: [twig.extension]
1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>
        <service id="Twig\Extensions\IntlExtension">
            <tag name="twig.extension" />
        </service>
    </services>
</container>
1
2
3
4
$container
    ->register('Twig\Extensions\IntlExtension')
    ->addTag('twig.extension')
;

twig.loader

Purpose: Register a custom service that loads Twig templates

By default, Symfony uses only one Twig Loader - FilesystemLoader. If you need to load Twig templates from another resource, you can create a service for the new loader and tag it with twig.loader.

If you use the default services.yaml configuration, the service will be automatically tagged thanks to autoconfiguration. But, you can also register it manually:

  • YAML
  • XML
  • PHP
1
2
3
4
services:
    App\Twig\CustomLoader:
        tags:
            - { name: twig.loader, priority: 0 }
1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>
        <service id="App\Twig\CustomLoader">
            <tag name="twig.loader" priority="0" />
        </service>
    </services>
</container>
1
2
3
4
5
6
use App\Twig\CustomLoader;

$container
    ->register(CustomLoader::class)
    ->addTag('twig.loader', ['priority' => 0])
;

Note

The priority is optional and its value is a positive or negative integer that defaults to 0. Loaders with higher numbers are tried first.

twig.runtime

Purpose: To register a custom Lazy-Loaded Twig Extension

Lazy-Loaded Twig Extensions are defined as regular services but the need to be tagged with twig.runtime. If you're using the default services.yaml configuration, the service is auto-registered and auto-tagged. But, you can also register it manually:

  • YAML
  • XML
  • PHP
1
2
3
services:
    App\Twig\AppExtension:
        tags: [twig.runtime]
1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>
        <service id="App\Twig\AppExtension">
            <tag name="twig.runtime" />
        </service>
    </services>
</container>
1
2
3
4
5
6
7
use App\Twig\AppExtension;
use App\Twig\AnotherExtension;

$container
    ->register(AppExtension::class)
    ->addTag('twig.runtime')
;

validator.constraint_validator

Purpose: Create your own custom validation constraint

This tag allows you to create and register your own custom validation constraint. For more information, read the How to Create a custom Validation Constraint article.

validator.initializer

Purpose: Register a service that initializes objects before validation

This tag provides a very uncommon piece of functionality that allows you to perform some sort of action on an object right before it's validated. For example, it's used by Doctrine to query for all of the lazily-loaded data on an object before it's validated. Without this, some data on a Doctrine entity would appear to be "missing" when validated, even though this is not really the case.

If you do need to use this tag, just make a new class that implements the ObjectInitializerInterface interface. Then, tag it with the validator.initializer tag (it has no options).

For an example, see the DoctrineInitializer class inside the Doctrine Bridge.

This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.
TOC
    Version
    We stand with Ukraine.
    Version:
    Become certified from home

    Become certified from home

    Peruse our complete Symfony & PHP solutions catalog for your web development needs.

    Peruse our complete Symfony & PHP solutions catalog for your web development needs.

    Symfony footer

    ↓ Our footer now uses the colors of the Ukrainian flag because Symfony stands with the people of Ukraine.

    Avatar of András Debreczeni, a Symfony contributor

    Thanks András Debreczeni for being a Symfony contributor

    1 commit • 2 lines changed

    View all contributors that help us make Symfony

    Become a Symfony contributor

    Be an active part of the community and contribute ideas, code and bug fixes. Both experts and newcomers are welcome.

    Learn how to contribute

    Symfony™ is a trademark of Symfony SAS. All rights reserved.

    • What is Symfony?

      • Symfony at a Glance
      • Symfony Components
      • Case Studies
      • Symfony Releases
      • Security Policy
      • Logo & Screenshots
      • Trademark & Licenses
      • symfony1 Legacy
    • Learn Symfony

      • Symfony Docs
      • Symfony Book
      • Reference
      • Bundles
      • Best Practices
      • Training
      • eLearning Platform
      • Certification
    • Screencasts

      • Learn Symfony
      • Learn PHP
      • Learn JavaScript
      • Learn Drupal
      • Learn RESTful APIs
    • Community

      • SymfonyConnect
      • Support
      • How to be Involved
      • Code of Conduct
      • Events & Meetups
      • Projects using Symfony
      • Downloads Stats
      • Contributors
      • Backers
    • Blog

      • Events & Meetups
      • A week of symfony
      • Case studies
      • Cloud
      • Community
      • Conferences
      • Diversity
      • Documentation
      • Living on the edge
      • Releases
      • Security Advisories
      • SymfonyInsight
      • Twig
      • SensioLabs
    • Services

      • SensioLabs services
      • Train developers
      • Manage your project quality
      • Improve your project performance
      • Host Symfony projects

      Deployed on

    Follow Symfony

    Search by Algolia