Search code examples
templatestypo3previewtypo3-10.x

How do i assign a template on PageLayoutView Preview in TYPO3 10?


I would like to assign a template on my PageLayoutView preview in order to avoid writing HTML on my PHP files and better maintain it. How can i achieve that using TYPO3 10?

I would like to use it for example on the textmedia content element and add the subheader in.


Solution

  • In order to achieve that, you will have to use the Standalone view. I would write a function which i can call it whenever i want to use it. Normally i would include the function on a Helper Class but for the sake of this answer i will put it on the same class. So lets say we have the textmedia content element and we want to add fields on the backend Preview.

    use TYPO3\CMS\Core\Utility\GeneralUtility;
    use TYPO3\CMS\Fluid\View\StandaloneView;
    
    /**
     * Contains a preview rendering for the page module of CType="textmedia"
     */
    class TextMediaPreviewRenderer implements PageLayoutViewDrawItemHookInterface
    {
        /**
         * Preprocesses the preview rendering of a content element of type "textmedia"
         *
         * @param \TYPO3\CMS\Backend\View\PageLayoutView $parentObject Calling parent object
         * @param bool $drawItem Whether to draw the item using the default functionality
         * @param string $headerContent Header content
         * @param string $subheaderContent Subheader content
         * @param string $itemContent Item content
         * @param array $row Record row of tt_content
         */
        public function preProcess(
            PageLayoutView &$parentObject,
            &$drawItem,
            &$headerContent,
            &$subheaderContent,
            &$itemContent,
            array &$row
        ) {
    
             if ($row['CType'] === 'textmedia') {
    
                 $standaloneView = $this->getStandAloneConfig();
    
                 /*Disable TYPO3's default backend view configuration */
                 $drawItem = false;
    
                   
                 /*Assign all the results to the backend */
                 $standaloneView->assignMultiple([
                    'title'             => $parentObject->CType_labels[$row['CType']],
                    'type'              => $row['CType'],
                    'content'           => $row,
                   
                 ]);
    
                 $itemContent .= $standaloneView->render();
             }
         }
    
         public function getStandAloneConfig()
         {
            $standaloneView = GeneralUtility::makeInstance(StandaloneView::class);
            $standaloneView->setLayoutRootPaths([10,'EXT:your_extension/Resources/Private/Backend/Layouts/']);
            $standaloneView->setTemplateRootPaths([10,'EXT:your_extension/Resources/Private/Backend/Templates/']);
            $standaloneView->setPartialRootPaths([10,'EXT:your_extension/Resources/Private/Backend/Partials/']);
            $standaloneView->setFormat('html');
            $standaloneView->setTemplate('PageLayoutView.html');
    
            return $standaloneView;
        }
    

    What is happening is the following

    First, we get the StandAlone configuration. In this configuration (getStandAloneConfig()) we set the path to where our templates, partials and layouts are. Then we assign the type (html) and then the name of the template where our preview is going to be built on (PageLayoutView.html).

    After that we reset everything that TYPO3 writes on the Preview ($drawItem = false;) so we can write our own.

    Last and not least we assign the variables which we are going to use on the HTML file.

    Under your_extension/Resources/Private/Backend/Templates/PageLayoutView.html

    <html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
        <f:switch expression="{type}">
            <f:case value="textmedia">
                <f:render partial="Textmedia" arguments="{_all}"/>
            </f:case>
            <f:case value="text">
                <f:render partial="Text" arguments="{_all}"/>
            </f:case>
           <f:defaultCase>
                <f:render partial="Header" arguments="{_all}"/>
            </f:defaultCase>
        </f:switch>
    </html>
    

    I personally use the PageLayoutView.html as a controller which decides, which partial should be rendered. So i assign the variable {type} and i render the partial based on its value.

    Under your_extension/Resources/Private/Backend/Partials/Textmedia.html

    <html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
    
       <p><strong class="element_title">{title}</strong></p>
       <table class="element_table">
          <tbody>
              <tr>
                 <th>Subheader</th>
                 <td>{content.subheader}</td>
              </tr>
          </tbody>
       </table>
    </html>
    

    Now you can look what is inside the {content} variable and render it on your HTML.

    If you want to style your Preview you can do the following: Under your ext_tables.php add the following line:

    $GLOBALS['TBE_STYLES']['stylesheet'] = 'EXT:your_extension/Resources/Public/Css/Backend/page-layout-view.css';