Localization in PHP¶
Sometimes you have to localize a string in PHP code, for example inside of a controller or a user function.
Which method of localization to use depends on the current context:
Localization in plain PHP¶
Localization in frontend context¶
In plain PHP use the class LanguageServiceFactory to create a LanguageService from the current site language:
<?php
declare(strict_types=1);
namespace MyVendor\MyExtension\Backend;
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Core\Localization\LanguageService;
use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
final class MyUserFunction
{
private LanguageServiceFactory $languageServiceFactory;
public function __construct(LanguageServiceFactory $languageServiceFactory) {
$this->languageServiceFactory = $languageServiceFactory;
}
private function getLanguageService(ServerRequestInterface $request): LanguageService
{
return $this->languageServiceFactory->createFromSiteLanguage(
$request->getAttribute('language')
?? $request->getAttribute('site')->getDefaultLanguage()
);
}
public function main(
string $content,
array $conf,
ServerRequestInterface $request
): string {
return $this->getLanguageService($request)->getLL(
'LLL:EXT:my_extension/Resources/Private/Language/locallang.xlf:something.'
);
}
}
Dependency injection should be available in most contexts where you need translations. Also the current request is available in entry point such as custom non-Extbase controllers, user functions, data processors etc.
Localization in backend context¶
In the backend context you should use the LanguageServiceFactory to create the required LanguageService.
<?php
declare(strict_types=1);
namespace MyVendor\MyExtension\Backend;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\CMS\Core\Localization\LanguageService;
use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
final class MyBackendClass
{
private LanguageServiceFactory $languageServiceFactory;
public function __construct(LanguageServiceFactory $languageServiceFactory)
{
$this->languageServiceFactory = $languageServiceFactory;
}
private function translateSomething(string $input): string
{
return $this->getLanguageService()->sL($input);
}
private function getLanguageService(): LanguageService
{
return $this->languageServiceFactory
->createFromUserPreferences($this->getBackendUserAuthentication());
}
private function getBackendUserAuthentication(): BackendUserAuthentication
{
return $GLOBALS['BE_USER'];
}
// ...
}
Attention
During development you are usually logged into the backend. So the global
variable $GLOBALS
might be available in the frontend. Once
logged out it is usually not available. Never depend on
$GLOBALS
in the frontend unless you know what you are doing.
Localization without context¶
If you should happen to be in a context where none of these are available, for example a static function, you can still do translations:
<?php
declare(strict_types=1);
namespace MyVendor\MyExtension\Utility;
use TYPO3\CMS\Core\Localization\LanguageServiceFactory;
use TYPO3\CMS\Core\Utility\GeneralUtility;
final class MyUtility
{
private static function translateSomething(string $lll): string
{
$languageServiceFactory = GeneralUtility::makeInstance(
LanguageServiceFactory::class
);
// As we are in a static context we cannot get the current request in
// another way this usually points to general flaws in your software-design
$request = $GLOBALS['TYPO3_REQUEST'];
$languageService = $languageServiceFactory->createFromSiteLanguage(
$request->getAttribute('language')
?? $request->getAttribute('site')->getDefaultLanguage()
);
return $languageService->sL($lll);
}
}
Localization in Extbase¶
In Extbase context you can use the method \TYPO3\CMS\Extbase\Utility\LocalizationUtility::translate($key, $extensionName).
This method requires the localization key as the first and the extension's
name as optional second parameter. For all available parameters
see below. Then the corresponding
text in the current language will be loaded from this extension's
locallang.
file.
The method translate
takes translation overrides from TypoScript into
account. See Changing localized terms using TypoScript.
Example¶
In this example the content of the flash message to be displayed in the backend gets translated:
use Psr\Http\Message\ResponseInterface;
use TYPO3\CMS\Core\Type\ContextualFeedbackSeverity;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
class ModuleController extends ActionController implements LoggerAwareInterface
{
/**
* Adds a count of entries to the flash message
*/
public function countAction(string $tablename = 'pages'): ResponseInterface
{
$count = $this->tableInformationService->countRecords($tablename);
$message = LocalizationUtility::translate(
key: 'record_count_message',
extensionName: 'examples',
arguments: [$count, $tablename]
);
$this->addFlashMessage(
messageBody: $message,
messageTitle: 'Information',
severity: ContextualFeedbackSeverity::INFO
);
return $this->redirect('flash');
}
}
The string in the translation file is defined like this:
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<!-- EXT:examples/Resources/Private/Language/locallang.xlf -->
<xliff version="1.0">
<file source-language="en" datatype="plaintext" original="messages" date="2013-03-09T18:44:59Z" product-name="examples">
<header />
<body>
<trans-unit id="new_relation" xml:space="preserve">
<source>Content element "%1$s" (uid: %2$d) has the following relations:</source>
</trans-unit>
</body>
</file>
</xliff>
The arguments
will be replaced in the localized strings by
the PHP function sprintf.
This behaviour is the same like in a Fluid translate ViewHelper with arguments.