Fluid standalone view in BE context

3.3k views Asked by At

Given you are in a BE or CLI context (e.g. sending emails via extbase command controller task), the following worked up to 7 LTS for rendering a fluid standalone view:

$view = $this->objectManager->get(StandaloneView::class);
$view->setTemplatePathAndFilename('/Absolute/Path/To/Template.html');
$view->setFormat('html');
$view->getRequest()->setControllerExtensionName('Myextensionname');
return trim($view->render());

However, in 8 LTS, this throws the following exception:

Tried resolving a template file for controller action "Standard->index" in format ".html", but none of the paths contained the expected template file… No paths configured.

As suggested in the wiki page at https://wiki.typo3.org/How_to_use_the_Fluid_Standalone_view_to_render_template_based_emails#Usage_in_TYPO3_8.7, I tried setting layout and partial root paths for the view:

$view->setLayoutRootPaths(['EXT:Myextensionname/Resources/Private/Layouts/']);
$view->setPartialRootPaths(['EXT:Myextensionname/Resources/Private/Partials/']);

However, this won't do the trick.

Digging a bit deeper, I could imagine that one would have to set the controller and action name, e.g. by setting the controller context, but that does not seem to be a solid solution as multiple other class instances are tied to it.

What is the correct way to render fluid standalone views in 8 LTS?

3

There are 3 answers

2
Claus Due On BEST ANSWER

StandaloneView likes to receive all template paths (partial, template and layout root paths) so if you don't already provide all of them, you should do so. The reason being that the naming "Standalone" refers to the view being tied neither to a specific MVC action nor a specific extension context.

That said, if you use 8.7.5 there's a chance you are hit by a regression that is going to be solved by https://review.typo3.org/#/c/53917/ so it might be worth checking that out before you do a major refactoring. Technically the StandaloneView can be operated like a TemplateView with extension context, it's just not officially supported behavior and TYPO3 may not consistently apply all of the context you expect.

0
Alex Kellner On

Here an example from our current webproject where we want to show a simple note in backend context based on a FLUID HTML in TYPO3 8.7

protected function renderMarkup(): string
    {
        $standaloneView = GeneralUtility::makeInstance(StandaloneView::class);
               $standaloneView->getRequest()->setControllerExtensionName('in2template');
        $templatePathAndFile = 'EXT:in2template/Resources/Private/Templates/Tca/ToolbarNoteEmptyFields.html';
$standaloneView->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName($templatePathAndFile));
        $standaloneView->assign('toolbar', 'toolbarstuff');
        return $standaloneView->render();
    }
0
René Pflamm On

In my 8.7 extension I use the following code to get the StandaloneView:

$extbaseFrameworkConfiguration = $this->configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
/** @var StandaloneView $emailView */
$emailView = $this->objectManager->get(StandaloneView::class);
$emailView->getRequest()->setControllerExtensionName($controllerExtensionName);
$emailView->getRequest()->setPluginName($pluginName);
$emailView->getRequest()->setControllerName($controllerName);
$emailView->setTemplateRootPaths($extbaseFrameworkConfiguration['view']['templateRootPaths']);
$emailView->setLayoutRootPaths($extbaseFrameworkConfiguration['view']['layoutRootPaths']);
$emailView->setPartialRootPaths($extbaseFrameworkConfiguration['view']['partialRootPaths']);
$emailView->setTemplate('Email/' . ucfirst($templateName));
$emailView->assignMultiple($variables);
$emailBody = $emailView->render();

In my function I gave the $controllerExtensionName, $pluginName and $controllerName as parameter with default values, so that other controllers/plugins can use this function, too.