[TASK] Make login_frameset.php dispatched
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Controller / BackendController.php
index 6abeeec..8dd1a57 100644 (file)
@@ -1,7 +1,7 @@
 <?php
 namespace TYPO3\CMS\Backend\Controller;
 
-/**
+/*
  * This file is part of the TYPO3 CMS project.
  *
  * It is free software; you can redistribute it and/or modify it under
@@ -19,7 +19,7 @@ use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
- * Class for rendering the TYPO3 backend version 4.2+
+ * Class for rendering the TYPO3 backend
  *
  * @author Ingo Renner <ingo@typo3.org>
  */
@@ -28,42 +28,37 @@ class BackendController {
        /**
         * @var string
         */
-       protected $content;
+       protected $content = '';
 
        /**
         * @var string
         */
-       protected $css;
+       protected $css = '';
 
        /**
         * @var array
         */
-       protected $cssFiles;
+       protected $cssFiles = array();
 
        /**
         * @var string
         */
-       protected $js;
+       protected $js = '';
 
        /**
         * @var array
         */
-       protected $jsFiles;
+       protected $jsFiles = array();
 
        /**
         * @var array
         */
-       protected $toolbarItems;
-
-       /**
-        * @var int Intentionally private as nobody should modify defaults
-        */
-       private $menuWidthDefault = 190;
+       protected $toolbarItems = array();
 
        /**
         * @var int
         */
-       protected $menuWidth;
+       protected $menuWidth = 190;
 
        /**
         * @var bool
@@ -71,6 +66,11 @@ class BackendController {
        protected $debug;
 
        /**
+        * @var string
+        */
+       protected $templatePath = 'EXT:backend/Resources/Private/Templates/';
+
+       /**
         * @var \TYPO3\CMS\Backend\Domain\Repository\Module\BackendModuleRepository
         */
        protected $backendModuleRepository;
@@ -104,78 +104,90 @@ class BackendController {
                $this->moduleLoader = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\Module\ModuleLoader::class);
                $this->moduleLoader->load($GLOBALS['TBE_MODULES']);
                $this->pageRenderer = $GLOBALS['TBE_TEMPLATE']->getPageRenderer();
-               $this->pageRenderer->loadScriptaculous('builder,effects,controls,dragdrop');
                $this->pageRenderer->loadExtJS();
-               $this->pageRenderer->loadJquery(NULL, NULL, \TYPO3\CMS\Core\Page\PageRenderer::JQUERY_NAMESPACE_DEFAULT_NOCONFLICT);
+               // included for the module menu JavaScript, please note that this is subject to change
+               $this->pageRenderer->loadJquery();
                $this->pageRenderer->enableExtJSQuickTips();
                $this->pageRenderer->addJsInlineCode('consoleOverrideWithDebugPanel', '//already done', FALSE);
                $this->pageRenderer->addExtDirectCode();
                // Add default BE javascript
-               $this->js = '';
                $this->jsFiles = array(
-                       'common' => 'sysext/backend/Resources/Public/JavaScript/common.js',
                        'locallang' => $this->getLocalLangFileName(),
                        'modernizr' => 'contrib/modernizr/modernizr.min.js',
                        'md5' => 'sysext/backend/Resources/Public/JavaScript/md5.js',
-                       'toolbarmanager' => 'sysext/backend/Resources/Public/JavaScript/toolbarmanager.js',
                        'modulemenu' => 'sysext/backend/Resources/Public/JavaScript/modulemenu.js',
                        'evalfield' => 'sysext/backend/Resources/Public/JavaScript/jsfunc.evalfield.js',
-                       'flashmessages' => 'sysext/backend/Resources/Public/JavaScript/flashmessages.js',
                        'tabclosemenu' => 'js/extjs/ux/ext.ux.tabclosemenu.js',
                        'notifications' => 'sysext/backend/Resources/Public/JavaScript/notifications.js',
                        'backend' => 'sysext/backend/Resources/Public/JavaScript/backend.js',
-                       'loginrefresh' => 'sysext/backend/Resources/Public/JavaScript/loginrefresh.js',
                        'debugPanel' => 'js/extjs/debugPanel.js',
                        'viewport' => 'js/extjs/viewport.js',
                        'iframepanel' => 'sysext/backend/Resources/Public/JavaScript/iframepanel.js',
                        'backendcontentiframe' => 'js/extjs/backendcontentiframe.js',
-                       'modulepanel' => 'js/extjs/modulepanel.js',
                        'viewportConfiguration' => 'js/extjs/viewportConfiguration.js',
                        'util' => 'sysext/backend/Resources/Public/JavaScript/util.js'
                );
-               if ($this->debug) {
-                       unset($this->jsFiles['loginrefresh']);
+               if (!$this->debug) {
+                       $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/LoginRefresh', 'function(LoginRefresh) {
+                               LoginRefresh.setLoginFramesetUrl(' . GeneralUtility::quoteJSvalue(BackendUtility::getModuleUrl('login_frameset')) . ');
+                       }');
                }
-               // Add default BE css
-               $this->pageRenderer->addCssLibrary('contrib/normalize/normalize.css', 'stylesheet', 'all', '', TRUE, TRUE);
 
-               // load the toolbar items
-               $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Toolbar/UserMenu');
+               // load FlashMessages functionality
+               $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/FlashMessages');
 
+               // load Modals
+               $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Modal');
+
+               // load Legacy CSS Support
+               $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/LegacyCssClasses');
+
+               // load the storage API and fill the UC into the PersistentStorage, so no additional AJAX call is needed
+               $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/Storage', 'function(Storage) {
+                       Storage.Persistent.load(' . json_encode($GLOBALS['BE_USER']->uc) . ');
+               }');
                $this->css = '';
-               $this->cssFiles = array();
-               $this->toolbarItems = array();
-               $this->initializeCoreToolbarItems();
-               $this->menuWidth = $this->menuWidthDefault;
-               if (isset($GLOBALS['TBE_STYLES']['dims']['leftMenuFrameW']) && (int)$GLOBALS['TBE_STYLES']['dims']['leftMenuFrameW'] != (int)$this->menuWidth) {
+
+               $this->initializeToolbarItems();
+               if (isset($GLOBALS['TBE_STYLES']['dims']['leftMenuFrameW'])) {
                        $this->menuWidth = (int)$GLOBALS['TBE_STYLES']['dims']['leftMenuFrameW'];
                }
                $this->executeHook('constructPostProcess');
        }
 
        /**
-        * Initializes the core toolbar items
+        * Initialize toolbar item objects
         *
+        * @throws \RuntimeException
         * @return void
         */
-       protected function initializeCoreToolbarItems() {
-               $coreToolbarItems = array(
-                       'shortcuts' => 'TYPO3\\CMS\\Backend\\Toolbar\\ShortcutToolbarItem',
-                       'clearCacheActions' => 'TYPO3\\CMS\\Backend\\Toolbar\\ClearCacheToolbarItem',
-                       'liveSearch' => 'TYPO3\\CMS\\Backend\\Toolbar\\LiveSearchToolbarItem'
-               );
-               foreach ($coreToolbarItems as $toolbarItemName => $toolbarItemClassName) {
-                       $toolbarItem = GeneralUtility::makeInstance($toolbarItemClassName, $this);
-                       // @TODO: Should throw as soon as "loading by convention" is implemented
-                       if (!$toolbarItem instanceof \TYPO3\CMS\Backend\Toolbar\ToolbarItemInterface) {
-                               continue;
+       protected function initializeToolbarItems() {
+               $toolbarItemInstances = array();
+               $classNameRegistry = $GLOBALS['TYPO3_CONF_VARS']['BE']['toolbarItems'];
+               foreach ($classNameRegistry as $className) {
+                       $toolbarItemInstance = GeneralUtility::makeInstance($className);
+                       if (!$toolbarItemInstance instanceof \TYPO3\CMS\Backend\Toolbar\ToolbarItemInterface) {
+                               throw new \RuntimeException(
+                                       'class ' . $className . ' is registered as toolbar item but does not implement'
+                                               . \TYPO3\CMS\Backend\Toolbar\ToolbarItemInterface::class,
+                                       1415958218
+                               );
                        }
-                       if ($toolbarItem->checkAccess()) {
-                               $this->toolbarItems[$toolbarItemName] = $toolbarItem;
-                       } else {
-                               unset($toolbarItem);
+                       $index = (int)$toolbarItemInstance->getIndex();
+                       if ($index < 0 || $index > 100) {
+                               throw new \RuntimeException(
+                                       'getIndex() must return an integer between 0 and 100',
+                                       1415968498
+                               );
                        }
+                       // Find next free position in array
+                       while(array_key_exists($index, $toolbarItemInstances)) {
+                               $index++;
+                       }
+                       $toolbarItemInstances[$index] = $toolbarItemInstance;
                }
+               ksort($toolbarItemInstances);
+               $this->toolbarItems = $toolbarItemInstances;
        }
 
        /**
@@ -187,23 +199,11 @@ class BackendController {
                $this->executeHook('renderPreProcess');
 
                // Prepare the scaffolding, at this point extension may still add javascript and css
-               $logo = GeneralUtility::makeInstance(\TYPO3\CMS\Backend\View\LogoView::class);
-
-               // Create backend scaffolding
-               $backendScaffolding = '
-                       <div class="navbar navbar-inverse x-hide-display" role="navigation" id="typo3-top-container">
-                               <div class="container-fluid">
-                                       <div class="navbar-header" id="typo3-logo">' .
-                                               $logo->render() .
-                                       '</div>
-                                       <div id="typo3-top">
-                                               <ul class="nav navbar-nav navbar-right typo3-top-toolbar" id="typo3-toolbar">' .
-                                                       $this->renderToolbar() .
-                                               '</ul>
-                                       </div>
-                               </div>
-                       </div>' .
-                       $this->generateModuleMenu();
+               $view = $this->getFluidTemplateObject($this->templatePath . 'Backend/Main.html');
+               // @todo: kick logo view class and move all logic to Fluid
+               $view->assign('logo', GeneralUtility::makeInstance(\TYPO3\CMS\Backend\View\LogoView::class)->render());
+               $view->assign('moduleMenu', $this->generateModuleMenu());
+               $view->assign('toolbar', $this->renderToolbar());
 
                /******************************************************
                 * Now put the complete backend document together
@@ -249,9 +249,8 @@ class BackendController {
                $this->pageRenderer->addExtOnReadyCode($extOnReadyCode);
                // Set document title:
                $title = $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] ? $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] . ' [TYPO3 CMS ' . TYPO3_version . ']' : 'TYPO3 CMS ' . TYPO3_version;
-               $this->content = $backendScaffolding;
                // Renders the module page
-               $this->content = $GLOBALS['TBE_TEMPLATE']->render($title, $this->content);
+               $this->content = $GLOBALS['TBE_TEMPLATE']->render($title, $view->render());
                $hookConfiguration = array('content' => &$this->content);
                $this->executeHook('renderPostProcess', $hookConfiguration);
                echo $this->content;
@@ -311,88 +310,54 @@ class BackendController {
         * @return string top toolbar elements as HTML
         */
        protected function renderToolbar() {
-               // Move search to last position
-               if (array_key_exists('liveSearch', $this->toolbarItems)) {
-                       $search = $this->toolbarItems['liveSearch'];
-                       unset($this->toolbarItems['liveSearch']);
-               }
-
-               $toolbar = '';
-
-               foreach ($this->toolbarItems as $key => $toolbarItem) {
-                       $menu = $toolbarItem->render();
-                       if ($menu) {
-                               // @TODO: Should throw as soon as "loading by convention" is implemented
-                               if ($toolbarItem instanceof \TYPO3\CMS\Backend\Toolbar\ToolbarItemInterface) {
-                                       $classes = $toolbarItem->getExtraClasses();
-                                       if ($toolbarItem->getDropdown()) {
-                                               $classes[] = 'dropdown';
-                                       }
-
-                                       $class = implode(' ', $classes);
-                                       if ($class !== '') {
-                                               $class = ' class="' . $class . '"';
-                                       }
-                                       $toolbar .= '<li' . $class . ' id="' . $toolbarItem->getIdAttribute() . '"' . $toolbarItem->getAdditionalAttributes() . '>' . $menu . '</li>';
-                               }
-                       }
-               }
+               $toolbar = array();
+               foreach ($this->toolbarItems as $toolbarItem) {
+                       /** @var \TYPO3\CMS\Backend\Toolbar\ToolbarItemInterface $toolbarItem */
+                       if ($toolbarItem->checkAccess()) {
+                               $hasDropDown = (bool)$toolbarItem->hasDropDown();
+                               $additionalAttributes = (array)$toolbarItem->getAdditionalAttributes();
 
-               $toolbar .= $this->renderUserToolbar();
+                               $liAttributes = array();
 
-               if ($search) {
-                       $toolbar .= '<li ' . $search->getAdditionalAttributes() . ' role="menu">' . $search->render() . '</li>';
-               }
-               return $toolbar;
-       }
+                               // Merge class: Add dropdown class if hasDropDown, add classes from additonal attributes
+                               $classes = array();
+                               if ($hasDropDown) {
+                                       $classes[] = 'dropdown';
+                               }
+                               if (isset($additionalAttributes['class'])) {
+                                       $classes[] = $additionalAttributes['class'];
+                                       unset($additionalAttributes['class']);
+                               }
+                               $liAttributes[] = 'class="' . implode(' ', $classes) . '"';
 
-       /**
-        * Gets the label of the BE user currently logged in
-        *
-        * @return string Html code snippet displaying the currently logged in user
-        */
-       protected function renderUserToolbar() {
-               $css = 'dropdown';
-               $icon = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('status-user-' . ($GLOBALS['BE_USER']->isAdmin() ? 'admin' : 'backend'));
-               $realName = $GLOBALS['BE_USER']->user['realName'];
-               $username = $GLOBALS['BE_USER']->user['username'];
-               $label = $realName ?: $username;
-               $title = $username;
-
-               // Superuser mode
-               if ($GLOBALS['BE_USER']->user['ses_backuserid']) {
-                       $css .= ' su-user';
-                       $title = $GLOBALS['LANG']->getLL('switchtouser') . ': ' . $username;
-                       $label = $GLOBALS['LANG']->getLL('switchtousershort') . ' ' . ($realName ? $realName . ' (' . $username . ')' : $username);
-               }
+                               // Add further attributes
+                               foreach($additionalAttributes as $name => $value) {
+                                       $liAttributes[] = $name . '="' . $value . '"';
+                               }
 
-               $toolbar = '<ul class="dropdown-menu" role="menu">';
-
-               /** @var \TYPO3\CMS\Backend\Domain\Model\Module\BackendModule $userModuleMenu */
-               $userModuleMenu = $this->backendModuleRepository->findByModuleName('user');
-               if ($userModuleMenu != FALSE && $userModuleMenu->getChildren()->count() > 0) {
-                       foreach ($userModuleMenu->getChildren() as $key => $module) {
-                               $moduleIcon = $module->getIcon();
-                               $toolbar .= '
-                                       <li id="' . $module->getName() . '" class="t3-menuitem-submodule submodule mod-' . $module->getName() . '" data-modulename="' . $module->getName() . '" data-navigationcomponentid="' . $module->getNavigationComponentId() . '" data-navigationframescript="' . $module->getNavigationFrameScript() . '" data-navigationframescriptparameters="' . $module->getNavigationFrameScriptParameters() . '">
-                                               <a title="' .$module->getDescription() . '" href="' . $module->getLink() . '" class="modlink">
-                                                       <span class="submodule-icon">' . ($moduleIcon['html'] ?: $moduleIcon['html']) . '</span>
-                                                       <span class="submodule-label">' . $module->getTitle() . '</span>
-                                               </a>
-                                       </li>';
+                               // Create a unique id from class name
+                               $className = get_class($toolbarItem);
+                               $className = GeneralUtility::underscoredToLowerCamelCase($className);
+                               $className = GeneralUtility::camelCaseToLowerCaseUnderscored($className);
+                               $className = str_replace(array('_', '\\'), '-', $className);
+                               $liAttributes[] = 'id="' . $className . '"';
+
+                               $toolbar[] = '<li ' . implode(' ', $liAttributes) . '>';
+
+                               if ($hasDropDown) {
+                                       $toolbar[] = '<a href="#" class="dropdown-toggle" data-toggle="dropdown">';
+                                       $toolbar[] = $toolbarItem->getItem();
+                                       $toolbar[] = '</a>';
+                                       $toolbar[] = '<div class="dropdown-menu" role="menu">';
+                                       $toolbar[] = $toolbarItem->getDropDown();
+                                       $toolbar[] = '</div>';
+                               } else {
+                                       $toolbar[] = $toolbarItem->getItem();
+                               }
+                               $toolbar[] = '</li>';
                        }
-                       $toolbar .= '<li class="divider"></li>';
                }
-
-               $toolbar .= '<li>' . $this->renderLogoutButton() . '</li>';
-               $toolbar .= '</ul>';
-
-               return '<li id="topbar-user-menu" class="' . $css . '" role="menu">' .
-                       '<a href="#" class="dropdown-toggle" data-toggle="dropdown">' .
-                       $icon . '<span title="' . htmlspecialchars($title) . '">' . htmlspecialchars($label) . ' <span class="caret"></span></span>' .
-                       '</a>' .
-                       $toolbar .
-               '</li>';
+               return implode(LF, $toolbar);
        }
 
        /**
@@ -515,6 +480,26 @@ class BackendController {
         * @return void
         */
        protected function generateJavascript() {
+
+               // Needed for FormEngine manipulation (date picker)
+               $dateFormat = ($GLOBALS['TYPO3_CONF_VARS']['SYS']['USdateFormat'] ? array('MM-DD-YYYY', 'HH:mm MM-DD-YYYY') : array('DD-MM-YYYY', 'HH:mm DD-MM-YYYY'));
+               $this->pageRenderer->addInlineSetting('DateTimePicker', 'DateFormat', $dateFormat);
+               // define the window size of the element browser etc.
+               $popupWindowSize = trim($GLOBALS['BE_USER']->getTSConfigVal('options.popupWindowSize'));
+               if (!empty($popupWindowSize)) {
+                       list($popupWindowWidth, $popupWindowHeight) = GeneralUtility::trimExplode('x', $popupWindowSize);
+               }
+               $popupWindowWidth  = !empty($popupWindowWidth) ? (int)$popupWindowWidth : 700;
+               $popupWindowHeight = !empty($popupWindowHeight) ? (int)$popupWindowHeight : 750;
+
+               // define the window size of the popups within the RTE
+               $rtePopupWindowSize = trim($GLOBALS['BE_USER']->getTSConfigVal('options.rte.popupWindowSize'));
+               if (!empty($rtePopupWindowSize)) {
+                       list($rtePopupWindowWidth, $rtePopupWindowHeight) = GeneralUtility::trimExplode('x', $rtePopupWindowSize);
+               }
+               $rtePopupWindowWidth  = !empty($rtePopupWindowWidth) ? (int)$rtePopupWindowWidth : ($popupWindowWidth-200);
+               $rtePopupWindowHeight = !empty($rtePopupWindowHeight) ? (int)$rtePopupWindowHeight : ($popupWindowHeight-250);
+
                $pathTYPO3 = GeneralUtility::dirname(GeneralUtility::getIndpEnv('SCRIPT_NAME')) . '/';
                // If another page module was specified, replace the default Page module with the new one
                $newPageModule = trim($GLOBALS['BE_USER']->getTSConfigVal('options.overridePageModule'));
@@ -522,10 +507,6 @@ class BackendController {
                if (!$GLOBALS['BE_USER']->check('modules', $pageModule)) {
                        $pageModule = '';
                }
-               $menuFrameName = 'menu';
-               if ($GLOBALS['BE_USER']->uc['noMenuMode'] === 'icons') {
-                       $menuFrameName = 'topmenuFrame';
-               }
                // Determine security level from conf vars and default to super challenged
                if ($GLOBALS['TYPO3_CONF_VARS']['BE']['loginSecurityLevel']) {
                        $this->loginSecurityLevel = $GLOBALS['TYPO3_CONF_VARS']['BE']['loginSecurityLevel'];
@@ -554,6 +535,14 @@ class BackendController {
                                'width' => 600,
                                'height' => 400
                        ),
+                       'PopupWindow' => array(
+                               'width' => $popupWindowWidth,
+                               'height' => $popupWindowHeight
+                       ),
+                       'RTEPopupWindow' => array(
+                               'width' => $rtePopupWindowWidth,
+                               'height' => $rtePopupWindowHeight
+                       )
                );
                $this->js .= '
        TYPO3.configuration = ' . json_encode($t3Configuration) . ';
@@ -690,7 +679,7 @@ class BackendController {
         * @throws \InvalidArgumentException
         */
        public function addJavascript($javascript) {
-               // TODO do we need more checks?
+               // @todo do we need more checks?
                if (!is_string($javascript)) {
                        throw new \InvalidArgumentException('parameter $javascript must be of type string', 1195129553);
                }
@@ -705,7 +694,7 @@ class BackendController {
         */
        public function addJavascriptFile($javascriptFile) {
                $jsFileAdded = FALSE;
-               //TODO add more checks if necessary
+               // @todo add more checks if necessary
                if (file_exists(GeneralUtility::resolveBackPath(PATH_typo3 . $javascriptFile))) {
                        $this->jsFiles[] = $javascriptFile;
                        $jsFileAdded = TRUE;
@@ -749,18 +738,10 @@ class BackendController {
         * @param string $toolbarItemClassName Toolbar item class name, f.e. tx_toolbarExtension_coolItem
         * @return void
         * @throws \UnexpectedValueException
+        * @deprecated since TYPO3 CMS 7, will be removed in TYPO3 CMS 8. Toolbar items are registered in $GLOBALS['TYPO3_CONF_VARS']['BE']['toolbarItems'] now.
         */
        public function addToolbarItem($toolbarItemName, $toolbarItemClassName) {
-               $toolbarItem = GeneralUtility::makeInstance($toolbarItemClassName, $this);
-               if (!$toolbarItem instanceof \TYPO3\CMS\Backend\Toolbar\ToolbarItemInterface) {
-                       // @TODO: Should throw as soon as "loading by convention" is implemented
-                       return;
-               }
-               if ($toolbarItem->checkAccess()) {
-                       $this->toolbarItems[$toolbarItemName] = $toolbarItem;
-               } else {
-                       unset($toolbarItem);
-               }
+               GeneralUtility::logDeprecatedFunction();
        }
 
        /**
@@ -785,17 +766,6 @@ class BackendController {
        }
 
        /**
-        * Renders the logout button form
-        *
-        * @return string Html code snippet displaying the logout button
-        */
-       protected function renderLogoutButton() {
-               // show logout or "exit" (from switch user mode) label
-               $buttonLabel = 'LLL:EXT:lang/locallang_core.xlf:' . ($GLOBALS['BE_USER']->user['ses_backuserid'] ? 'buttons.exit' : 'buttons.logout');
-               return '<a href="logout.php" target="_top">' . $GLOBALS['LANG']->sL($buttonLabel, TRUE) . '</a>';
-       }
-
-       /**
         * loads all modules from the repository
         * and renders it with a template
         *
@@ -803,11 +773,9 @@ class BackendController {
         */
        protected function generateModuleMenu() {
                // get all modules except the user modules for the side menu
-               $moduleStorage = $this->backendModuleRepository->loadAllowedModules(array('user'));
+               $moduleStorage = $this->backendModuleRepository->loadAllowedModules(array('user', 'help'));
 
-               /** @var $view \TYPO3\CMS\Fluid\View\StandaloneView */
-               $view = GeneralUtility::makeInstance(\TYPO3\CMS\Fluid\View\StandaloneView::class);
-               $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Templates/ModuleMenu/Main.html'));
+               $view = $this->getFluidTemplateObject($this->templatePath . 'ModuleMenu/Main.html');
                $view->assign('modules', $moduleStorage);
                return $view->render();
        }
@@ -824,4 +792,19 @@ class BackendController {
                $ajaxRequestHandler->addContent('menu', $content);
                $ajaxRequestHandler->setContentFormat('json');
        }
+
+       /**
+        * returns a new standalone view, shorthand function
+        *
+        * @param string $templatePathAndFileName optional the path to set the template path and filename
+        * @return \TYPO3\CMS\Fluid\View\StandaloneView
+        */
+       protected function getFluidTemplateObject($templatePathAndFileName = NULL) {
+               $view = GeneralUtility::makeInstance(\TYPO3\CMS\Fluid\View\StandaloneView::class);
+               if ($templatePathAndFileName) {
+                       $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName($templatePathAndFileName));
+               }
+               return $view;
+       }
+
 }