Feature: #89334 - Add generic TranslatorInterface 

See forge#89334

Description 

A new \TYPO3\CMS\Core\Localization\TranslatorInterface has been introduced that provides a clean abstraction for translating labels in TYPO3.

The interface defines two methods:

  • translate() — translates a label by its identifier and domain, supporting argument interpolation, a default fallback value, and per-call locale overrides.
  • label() — resolves full TYPO3 label reference strings (e.g. LLL:EXT:core/Resources/Private/Language/locallang.xlf:my.key) and delegates to translate(). This method serves as the interface-based equivalent of LanguageService::sL(), with the key differences that it returns null when a label cannot be resolved (instead of an empty string) and supports argument interpolation, default values, and locale overrides.

The existing LanguageService now implements this interface, making it possible to type-hint against the interface instead of the concrete class.

Example usage:

Using TranslatorInterface via dependency injection
use TYPO3\CMS\Core\Localization\TranslatorInterface;

final class MyController
{
    public function __construct(
        private readonly TranslatorInterface $translator,
    ) {}

    public function someAction(): void
    {
        // Translate by identifier and domain
        $label = $this->translator->translate(
            'button.save',
            'my_extension.messages',
        );

        // Translate by identifier and filename (discouraged)
        $label = $this->translator->translate(
            'button.save',
            'EXT:my_extension/Resources/Private/Language/locallang.xlf',
        );

        // Translate with arguments
        $label = $this->translator->translate(
            'record.count',
            'my_extension.messages',
            [5],
        );

        // Translate with a default fallback
        $label = $this->translator->translate(
            'missing.key',
            'my_extension.messages',
            [],
            'Fallback text',
        );

        // Label reference with arguments and default
        $label = $this->translator->label(
            'my_extension.messages:record.count',
            [5],
            'Fallback text',
        );

        // Resolve a full label reference string with file and LLL prefix (discouraged)
        $label = $this->translator->label(
            'LLL:EXT:my_extension/Resources/Private/Language/locallang.xlf:button.save',
        );

    }
}
Copied!

The label() method accepts the following reference formats:

  • my_extension.messages:my.key
  • EXT:my_extension/Resources/Private/Language/locallang.xlf:my.key
  • LLL:EXT:my_extension/Resources/Private/Language/locallang.xlf:my.key

The LLL: prefix is optional and stripped before resolution.

Impact 

Extension developers can now type-hint against TranslatorInterface instead of the concrete LanguageService class. This improves testability and decouples code from the specific implementation.

The translate() method of LanguageService has been extended with two additional optional parameters:

  • $default — a fallback value returned when the label is not found
  • $locale — allows overriding the locale on a per-call basis