Monday, February 5, 2018

TYPO3 - How to render a Fluid standalone view multiple times in different languages

Back in 2015, I wrote 2 blogposts (first and second) about rendering a localized Fluid standalone view in a scheduler task (commandController). The main problem was to render a Fluid standalone view multiple times within the same request but with different languages. Back then, my solution was to create an own ViewHelper and a modified version of the TYPO3 LocalizationUtility which were responsible for handling the localization changes during the rendering request.

Meanwhile, I got feedback from readers of my blog pointing me to a more simple solution for the problem.

The main problem with changing the TYPO3 backend language during one request is the language cache, which is only initialized once for the current language. So when you switch the backend language multiple times, the cached language files for the previous language will still be used.

The solution is to unset the language cache for the extension you are rendering your Fluid standalone view from. In order to do so, you have to extend the TYPO3 LocalizationUtility with a new function as shown below.


class LocalizationUtility extends \TYPO3\CMS\Extbase\Utility\LocalizationUtility
{
    /**
     * Resets the language cache for the given extension key
     *
     * @param string $extensionName
     */
    public static function resetLocalizationCache($extensionName)
    {
        unset(static::$LOCAL_LANG[$extensionName]);
    }
}

The example code below shows, how to use the resetLocalizationCache method before rendering a Fluid standalone view in a given language.


/**
 * Renders a Fluid StandaloneView respecting the given language
 *
 * @param string $language The language (e.g. de, dk or se)
 * @return string
 */
public function renderStandaloneView($language = '')
{
    // Set the extensionKey
    $extensionKey = GeneralUtility::underscoredToUpperCamelCase('standaloneview');

    if ($language !== '') {
        // Temporary set Language of current BE user to given language
        $GLOBALS['BE_USER']->uc['lang'] = $language;
        LocalizationUtility::resetLocalizationCache($extensionKey);
    }

    /** @var \TYPO3\CMS\Fluid\View\StandaloneView $view */
    $view = $this->objectManager->get(StandaloneView::class);
    $view->setFormat('html');
    $template = GeneralUtility::getFileAbsFileName(
        'EXT:standaloneview/Resources/Private/Templates/StandaloneView.html'
    );
    $view->setTemplatePathAndFilename($template);

    // Set Extension name, so localizations for extension get respected
    $view->getRequest()->setControllerExtensionName($extensionKey);

    return $view->render();
}

So with a small extension of the LocalizationUtility it is now easily possible to render a Fluid standalone view in a language of choice and it is also possible to switch the language within the same request (e.g. sending out localized e-mails to multiple recipients).

I updated the Demo-Extension, which contains a backend module and a command controller for demonstration purposes.

I would like to thank Johannes Rebhan for giving me the hint about the localization cache and also Ulrich Fischer for showing me a different approach, which requires more code, but lead to the same result.


No comments:

Post a Comment