Für mein aktuelles Projekt sollte es etwas abgefahrenes sein: In einem Template sollen nebeneinander ein Wort in Sprache 1 und dann das gleiche Wort in Sprache 2 ausgegeben werden. Problem ist, das der <f:translate key="" />
ViewHelper immer nur mit der aktuellen Sprache arbeitet. Mein Ansatz ist also einen eigenen ViewHelper zu schreiben. Nun ruft der TranslateViewHelper (in einer statischen Funktion) die LocalizationUtility auf und diese liefert die Übersetzung. d.h. ich werde wohl auch eine eigene LocalizationUtility brauchen.
Mein ViewHelper soll in der Verwendung so aussehen: <my:translate key="lang[fr]:years" />
Ich kann/möchte kein weiteres Argument an den ViewHelper dranhängen, weil mein TranslateViewHelper dann nicht mehr von zum Teil statischen Core-TranslateViewHelper ableiten kann. Und der $key wird eh durchgereicht, also nutze ich den Key, um meine Sprache zu definieren.
Eigenen TranslateViewHelper implementieren, der „meine“ LocalizationUtility nutzt
namespace My\Extension\ViewHelper; use My\Extension\Utility\LocalizationUtility; class TranslateViewHelper extends \TYPO3\CMS\Fluid\ViewHelpers\TranslateViewHelper { protected static function translate($id, $extensionName, $arguments) { return LocalizationUtility::translate($id, $extensionName, $arguments); } }
Dann muss „nur“ noch die LocalizationUtility angepasst werden. In der translate-Funktion wird der $key geparst und falls er einen Hinweis auf eine konkrete Sprache enthält, wird diese in $overrideLanguageKey gesetzt. Wichtig ist keine der anderen Variablen zu ändern, denn sobald ich sie für ein Label ändere, gilt die Änderung für alle folgenden Labels. Später überprüfe ich, ob $overrideLanguageKey gesetzt ist, lade die Übersetzungen und liefere die angeforderte Übersetzung zurück. Das ist nicht der komplette Code, sondern nur die relevanten Auszüge.
<?php namespace My\Extension\Utility; class LocalizationUtility extends \TYPO3\CMS\Extbase\Utility\LocalizationUtility { /** * @var string */ protected static $overrideLanguageKey = ''; /** * Returns the localized label of the LOCAL_LANG key, $key. * * @param string $key The key from the LOCAL_LANG array for which to return the value. * @param string $extensionName The name of the extension * @param array $arguments the arguments of the extension, being passed over to vsprintf * @return string|NULL The value from LOCAL_LANG or NULL if no translation was found. */ public static function translate($key, $extensionName, $arguments = null) { if (GeneralUtility::isFirstPartOfStr($key, 'lang[')) { preg_match('#^lang\[(.*?)\]\:(.*?)$#', $key, $matches); // set key $key = $matches[2]; self::$overrideLanguageKey = $matches[1]; } [...] self::initializeLocalization($extensionName); /* NEW */ $languageKey = self::$languageKey; if(self::$overrideLanguageKey) { self::initializeLocalizationFor($extensionName, self::$overrideLanguageKey); $languageKey = self::$overrideLanguageKey; } // The "from" charset of csConv() is only set for strings from TypoScript via _LOCAL_LANG if (!empty(self::$LOCAL_LANG[$extensionName][$languageKey][$key][0]['target']) || isset(self::$LOCAL_LANG_UNSET[$extensionName][$languageKey][$key]) ) { // Local language translation for key exists $value = self::$LOCAL_LANG[$extensionName][$languageKey][$key][0]['target']; } elseif (!empty(self::$alternativeLanguageKeys)) { [...] } /** * @param string $extensionName * @param string $languageKey * @return void */ protected static function initializeLocalizationFor($extensionName, $languageKey) { $locallangPathAndFilename = 'EXT:' . GeneralUtility::camelCaseToLowerCaseUnderscored($extensionName) . '/' . self::$locallangPath . 'locallang.xlf'; $renderCharset = TYPO3_MODE === 'FE' ? self::getTypoScriptFrontendController()->renderCharset : self::getLanguageService()->charSet; /** @var $languageFactory LocalizationFactory */ $languageFactory = GeneralUtility::makeInstance(LocalizationFactory::class); self::$LOCAL_LANG[$extensionName] = $languageFactory->getParsedData($locallangPathAndFilename, $languageKey, $renderCharset); } }
Im Template können schließlich beide TranslateViewHelper nebeneinander verwendet werden:
<f:translate key="years" /> <my:translate key="lang[fr]:years" />