Search code examples
typo3partialfluidextbase

TYPO3 Render FLUID Template in Backend


I have an extbase extension with this TCA:

$GLOBALS['TCA']['tt_content']['types']['list']['previewRenderer']['items_item']
= \Vendor\Name\Backend\Preview\PreviewRenderer::class;

and this tsconfig:

mod.web_layout.tt_content.preview.list.items_item = EXT:EXT/Resources/Private/Templates/Preview/Items.html

Everything works well if i write the complete Code in this template file. But if i change it and use Partials like this:

<f:render arguments="{_all}" partial="Preview/List"/>

I only get the following error:

Error while rendering FluidTemplate preview using /typo3conf/ext/EXT/Resources/Private/Templates/Preview/Items.html The Fluid template files "" could not be loaded.

How can i set the Partial and Layout path? Ive tried ist with module via typoscript but it doesnt work.


Solution

  • It depends on what your PreviewRender is doing.

    The StandardContentPreviewRenderer supports only a template-file, no layouts, no partials. It's using a FluidStandaloneView and only setting setTemplatePathAndFilename() without setting paths for other parts of the template (renderContentElementPreviewFromFluidTemplate()):

     protected function ‪renderContentElementPreviewFromFluidTemplate(array $row): ?string
     {
         $tsConfig = BackendUtility::getPagesTSconfig($row['pid'])['mod.']['web_layout.']['tt_content.']['preview.'] ?? [];
         $fluidTemplateFile = '';
    
         if ($row['CType'] === 'list' && !empty($row['list_type'])
             && !empty($tsConfig['list.'][$row['list_type']])
         ) {
             $fluidTemplateFile = $tsConfig['list.'][$row['list_type']];
         } elseif (!empty($tsConfig[$row['CType']])) {
             $fluidTemplateFile = $tsConfig[$row['CType']];
         }
    
         if ($fluidTemplateFile) {
             $fluidTemplateFile = GeneralUtility::getFileAbsFileName($fluidTemplateFile);
             if ($fluidTemplateFile) {
                 try {
                     $view = GeneralUtility::makeInstance(StandaloneView::class);
                     $view->setTemplatePathAndFilename($fluidTemplateFile);
                     $view->assignMultiple($row);
                     if (!empty($row['pi_flexform'])) {
                         $flexFormService = GeneralUtility::makeInstance(FlexFormService::class);
                         $view->assign('pi_flexform_transformed', $flexFormService->convertFlexFormContentToArray($row['pi_flexform']));
                     }
                     return $view->render();
                 } catch (\‪Exception $e) {
                     $this->logger->warning('The backend preview for content element {uid} can not be rendered using the Fluid template file "{file}"', [
                         'uid' => $row['uid'],
                         'file' => $fluidTemplateFile,
                         'exception' => $e,
                     ]);
    
                     if (‪$GLOBALS['TYPO3_CONF_VARS']['BE']['debug'] && $this->‪getBackendUser()->isAdmin()) {
                         $view = GeneralUtility::makeInstance(StandaloneView::class);
                         $view->assign('error', [
                             'message' => str_replace(‪Environment::getProjectPath(), '', $e->getMessage()),
                             'title' => 'Error while rendering FluidTemplate preview using ' . str_replace(‪Environment::getProjectPath(), '', $fluidTemplateFile),
                         ]);
                         $view->setTemplateSource('<f:be.infobox title="{error.title}" state="2">{error.message}</f:be.infobox>');
                         return $view->render();
                     }
                 }
             }
         }
         return null;
     }
    

    If you want more advanced features in your preview, you have to extend/override this method.


    Update:

    StandaloneView extends TYPO3\CMS\Fluid\View\AbstractTemplateView, so you have also those setters:

    • setTemplate($templateName)
    • setTemplatePathAndFilename($templatePathAndFilename)
    • setTemplateRootPaths(array $templateRootPaths)
    • setPartialRootPaths(array $partialRootPaths)
    • setLayoutRootPaths(array $layoutRootPaths)

    So setting paths for partials in your ‪renderContentElementPreviewFromFluidTemplate() should solve it:

     $view->setPartialRootPaths([
       \TYPO3\CMS\Core\Utility\GeneralUtility::getFileAbsFileName('EXT:extensionfolder/Resources/Private/Partials'),
     ]);