[TASK] Port toolbar dropdowns to Fluid 29/40329/13
authorAndreas Fernandez <a.fernandez@scripting-base.de>
Tue, 16 Jun 2015 19:52:05 +0000 (21:52 +0200)
committerMarkus Klein <markus.klein@typo3.org>
Sat, 20 Jun 2015 16:21:24 +0000 (18:21 +0200)
The toolbar dropdown menus are ported to Fluid. Also, some small
improvements are made in this patch.

Resolves: #67537
Related: #67568
Releases: master
Change-Id: I41b502e97108494bf6d4acfa0dedb32bb18a5e18
Reviewed-on: http://review.typo3.org/40329
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Tested-by: Wouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Markus Klein <markus.klein@typo3.org>
Tested-by: Markus Klein <markus.klein@typo3.org>
14 files changed:
typo3/sysext/backend/Classes/Backend/ToolbarItems/AbstractToolbarItem.php
typo3/sysext/backend/Classes/Backend/ToolbarItems/ClearCacheToolbarItem.php
typo3/sysext/backend/Classes/Backend/ToolbarItems/HelpToolbarItem.php
typo3/sysext/backend/Classes/Backend/ToolbarItems/ShortcutToolbarItem.php
typo3/sysext/backend/Classes/Backend/ToolbarItems/SystemInformationToolbarItem.php
typo3/sysext/backend/Classes/Backend/ToolbarItems/UserToolbarItem.php
typo3/sysext/backend/Resources/Private/Templates/ToolbarMenu/ClearCache.html [new file with mode: 0644]
typo3/sysext/backend/Resources/Private/Templates/ToolbarMenu/Help.html [new file with mode: 0644]
typo3/sysext/backend/Resources/Private/Templates/ToolbarMenu/Shortcut.html [new file with mode: 0644]
typo3/sysext/backend/Resources/Private/Templates/ToolbarMenu/User.html [new file with mode: 0644]
typo3/sysext/opendocs/Classes/Backend/ToolbarItems/OpendocsToolbarItem.php
typo3/sysext/opendocs/Resources/Private/Templates/ToolbarMenu/Opendocs.html [new file with mode: 0644]
typo3/sysext/workspaces/Classes/Backend/ToolbarItems/WorkspaceSelectorToolbarItem.php
typo3/sysext/workspaces/Resources/Private/Templates/ToolbarMenu/WorkspaceSelector.html [new file with mode: 0644]

index 9ddf47e..98f9f2a 100644 (file)
@@ -24,26 +24,46 @@ use TYPO3\CMS\Fluid\View\StandaloneView;
 abstract class AbstractToolbarItem {
 
        /**
+        * @var string Extension context
+        */
+       protected $extension = 'backend';
+
+       /**
+        * @var string Template file for the dropdown menu
+        */
+       protected $templateFile = '';
+
+       /**
         * @var StandaloneView
         */
        protected $standaloneView = NULL;
 
+       /**
+        * Constructor
+        *
+        * @throws \InvalidArgumentException
+        */
        public function __construct() {
-               $extPath = ExtensionManagementUtility::extPath('backend');
+               if (empty($this->templateFile)) {
+                       throw new \InvalidArgumentException('The template file for class "' . get_class($this) . '" is not set.', 1434530382);
+               }
+
+               $extPath = ExtensionManagementUtility::extPath($this->extension);
                /* @var $view StandaloneView */
                $this->standaloneView = GeneralUtility::makeInstance(StandaloneView::class);
-               $this->standaloneView->setTemplatePathAndFilename($extPath . 'Resources/Private/Templates/ToolbarMenu/' . static::TOOLBAR_MENU_TEMPLATE);
+               $this->standaloneView->setTemplatePathAndFilename($extPath . 'Resources/Private/Templates/ToolbarMenu/' . $this->templateFile);
+               $this->standaloneView->setPartialRootPaths(array(
+                       $extPath . 'Resources/Private/Partials/ToolbarMenu/'
+               ));
        }
 
        /**
-        * @param string $extension Set the extension context (required for shorthand locallang.xlf references)
         * @return StandaloneView
         */
-       protected function getStandaloneView($extension = NULL) {
-               if (!empty($extension)) {
-                       $request = $this->standaloneView->getRequest();
-                       $request->setControllerExtensionName($extension);
-               }
+       protected function getStandaloneView() {
+               $request = $this->standaloneView->getRequest();
+               $request->setControllerExtensionName($this->extension);
+
                return $this->standaloneView;
        }
 }
index 658a1c6..f031186 100644 (file)
@@ -25,7 +25,12 @@ use TYPO3\CMS\Backend\Toolbar\ClearCacheActionsHookInterface;
  *
  * @author Ingo Renner <ingo@typo3.org>
  */
-class ClearCacheToolbarItem implements ToolbarItemInterface {
+class ClearCacheToolbarItem extends AbstractToolbarItem implements ToolbarItemInterface {
+
+       /**
+        * @var string Template file for the dropdown menu
+        */
+       protected $templateFile = 'ClearCache.html';
 
        /**
         * @var array
@@ -43,6 +48,8 @@ class ClearCacheToolbarItem implements ToolbarItemInterface {
         * @throws \UnexpectedValueException
         */
        public function __construct() {
+               parent::__construct();
+
                $backendUser = $this->getBackendUser();
                $languageService = $this->getLanguageService();
 
@@ -136,18 +143,20 @@ class ClearCacheToolbarItem implements ToolbarItemInterface {
         * @return string Drop down HTML
         */
        public function getDropDown() {
-               $result = array();
-               $result[] = '<ul class="dropdown-list">';
+               $items = array();
                foreach ($this->cacheActions as $cacheAction) {
                        $title = $cacheAction['description'] ?: $cacheAction['title'];
-                       $result[] = '<li>';
-                       $result[] = '<a class="dropdown-list-link" href="' . htmlspecialchars($cacheAction['href']) . '" title="' . htmlspecialchars($title) . '">';
-                       $result[] = $cacheAction['icon'] . ' ' . htmlspecialchars($cacheAction['title']);
-                       $result[] = '</a>';
-                       $result[] = '</li>';
+                       $items[] = array(
+                               'title' => $title,
+                               'label' => $cacheAction['title'],
+                               'href' => $cacheAction['href'],
+                               'icon' => $cacheAction['icon']
+                       );
                }
-               $result[] = '</ul>';
-               return implode(LF, $result);
+
+               $standaloneView = $this->getStandaloneView();
+               $standaloneView->assign('items', $items);
+               return $standaloneView->render();
        }
 
        /**
index e86af44..e3134c9 100644 (file)
@@ -22,7 +22,12 @@ use TYPO3\CMS\Backend\Domain\Model\Module\BackendModule;
 /**
  * Help toolbar item
  */
-class HelpToolbarItem implements ToolbarItemInterface {
+class HelpToolbarItem extends AbstractToolbarItem implements ToolbarItemInterface {
+
+       /**
+        * @var string Template file for the dropdown menu
+        */
+       protected $templateFile = 'Help.html';
 
        /**
         * @var \SplObjectStorage<BackendModule>
@@ -33,6 +38,8 @@ class HelpToolbarItem implements ToolbarItemInterface {
         * Constructor
         */
        public function __construct() {
+               parent::__construct();
+
                /** @var BackendModuleRepository $backendModuleRepository */
                $backendModuleRepository = GeneralUtility::makeInstance(BackendModuleRepository::class);
                /** @var \TYPO3\CMS\Backend\Domain\Model\Module\BackendModule $userModuleMenu */
@@ -68,26 +75,25 @@ class HelpToolbarItem implements ToolbarItemInterface {
         */
        public function getDropDown() {
                $dropdown = array();
-               $dropdown[] = '<ul class="dropdown-list">';
                foreach ($this->helpModuleMenu->getChildren() as $module) {
                        /** @var BackendModule $module */
-                       $moduleIcon = $module->getIcon();
-                       $dropdown[] ='<li'
-                               . ' id="' . htmlspecialchars($module->getName()) . '"'
-                               . ' class="typo3-module-menu-item submodule mod-' . htmlspecialchars($module->getName()) . '" '
-                               . ' data-modulename="' . htmlspecialchars($module->getName()) . '"'
-                               . ' data-navigationcomponentid="' . htmlspecialchars($module->getNavigationComponentId()) . '"'
-                               . ' data-navigationframescript="' . htmlspecialchars($module->getNavigationFrameScript()) . '"'
-                               . ' data-navigationframescriptparameters="' . htmlspecialchars($module->getNavigationFrameScriptParameters()) . '"'
-                               . '>';
-                       $dropdown[] = '<a title="' . htmlspecialchars($module->getDescription()) . '" href="' . htmlspecialchars($module->getLink()) . '" class="dropdown-list-link modlink">';
-                       $dropdown[] = '<span class="submodule-icon typo3-app-icon"><span><span>' . $moduleIcon . '</span></span></span>';
-                       $dropdown[] = '<span class="submodule-label">' . htmlspecialchars($module->getTitle()) . '</span>';
-                       $dropdown[] = '</a>';
-                       $dropdown[] = '</li>';
+                       $dropdown[] = array(
+                               'id' => $module->getName(),
+                               'navigation' => array(
+                                       'componentId' => $module->getNavigationComponentId(),
+                                       'frameScript' => $module->getNavigationFrameScript(),
+                                       'frameScriptParameters' => $module->getNavigationFrameScriptParameters(),
+                               ),
+                               'href' => $module->getLink(),
+                               'description' => $module->getDescription(),
+                               'icon' => $module->getIcon(),
+                               'label' => $module->getTitle()
+                       );
                }
-               $dropdown[] = '</ul>';
-               return implode(LF, $dropdown);
+
+               $standaloneView = $this->getStandaloneView();
+               $standaloneView->assign('dropdown', $dropdown);
+               return $standaloneView->render();
        }
 
        /**
index da5374d..d9a82d6 100644 (file)
@@ -28,14 +28,29 @@ use TYPO3\CMS\Core\Utility\PathUtility;
  *
  * @author Ingo Renner <ingo@typo3.org>
  */
-class ShortcutToolbarItem implements ToolbarItemInterface {
+class ShortcutToolbarItem extends AbstractToolbarItem implements ToolbarItemInterface {
 
        /**
-        * @const integer Number of super global group
+        * @const int Number of super global group
         */
        const SUPERGLOBAL_GROUP = -100;
 
        /**
+        * @const string Type of shortcut groups
+        */
+       const TYPE_GROUP = 'group';
+
+       /**
+        * @const string Type of shortcut items
+        */
+       const TYPE_ITEM = 'item';
+
+       /**
+        * @var string Template file for the dropdown menu
+        */
+       protected $templateFile = 'Shortcut.html';
+
+       /**
         * @var string
         */
        public $perms_clause;
@@ -76,6 +91,8 @@ class ShortcutToolbarItem implements ToolbarItemInterface {
                        $loadModules->load($GLOBALS['TBE_MODULES']);
                }
 
+               parent::__construct();
+
                // By default, 5 groups are set
                $this->shortcutGroups = array(
                        1 => '1',
@@ -126,65 +143,70 @@ class ShortcutToolbarItem implements ToolbarItemInterface {
                $editIcon = '<a href="#" class="dropdown-list-link-edit shortcut-edit">' . IconUtility::getSpriteIcon('actions-document-open', array('title' => $shortcutEdit)) . '</a>';
                $deleteIcon = '<a href="#" class="dropdown-list-link-delete shortcut-delete">' . IconUtility::getSpriteIcon('actions-edit-delete', array('title' => $shortcutDelete)) . '</a>';
 
-               $shortcutMenu[] = '<ul class="dropdown-list">';
+               $shortcutMenu = array();
 
                // Render shortcuts with no group (group id = 0) first
                $noGroupShortcuts = $this->getShortcutsByGroup(0);
                foreach ($noGroupShortcuts as $shortcut) {
-
-                       $shortcutMenu[] = '
-                               <li class="shortcut" data-shortcutid="' . (int)$shortcut['raw']['uid'] . '">
-                                       <a class="dropdown-list-link dropdown-link-list-add-editdelete" href="#" onclick="' . htmlspecialchars($shortcut['action']) . ' return false;">' .
-                                               $shortcut['icon'] . ' ' .
-                                               htmlspecialchars($shortcut['label']) .
-                                       '</a>
-                                       ' . $editIcon . $deleteIcon . '
-                               </li>';
+                       $shortcutMenu[] = array(
+                               'uid' => (int)$shortcut['raw']['uid'],
+                               'groupid' => static::SUPERGLOBAL_GROUP,
+                               'type' => static::TYPE_ITEM,
+                               'action' => $shortcut['action'],
+                               'icon' => $shortcut['icon'],
+                               'label' => $shortcut['label']
+                       );
                }
                // Now render groups and the contained shortcuts
                $groups = $this->getGroupsFromShortcuts();
                krsort($groups, SORT_NUMERIC);
                foreach ($groups as $groupId => $groupLabel) {
-                       if ($groupId != 0) {
-                               $shortcutGroup = '';
-                               if (count($shortcutMenu) > 1) {
-                                       $shortcutGroup .= '<li class="divider"></li>';
-                               }
-                               $shortcutGroup .= '
-                                       <li class="dropdown-header" id="shortcut-group-' . (int)$groupId . '">
-                                               ' . $groupLabel . '
-                                       </li>';
-                               $shortcuts = $this->getShortcutsByGroup($groupId);
-                               $i = 0;
-                               foreach ($shortcuts as $shortcut) {
-                                       $i++;
-                                       $shortcutGroup .= '
-                                       <li class="shortcut" data-shortcutid="' . (int)$shortcut['raw']['uid'] . '" data-shortcutgroup="' . (int)$groupId . '">
-                                               <a class="dropdown-list-link dropdown-link-list-add-editdelete" href="#" onclick="' . htmlspecialchars($shortcut['action']) . ' return false;">' .
-                                                       $shortcut['icon'] . ' ' .
-                                                       htmlspecialchars($shortcut['label']) .
-                                               '</a>
-                                               ' . $editIcon . $deleteIcon . '
-                                       </li>';
-                               }
-                               $shortcutMenu[] = $shortcutGroup;
+                       $groupId = (int)$groupId;
+                       if ($groupId === 0) {
+                               continue;
+                       }
+
+                       $shortcutMenu[] = array(
+                               'uid' => $groupId,
+                               'type' => static::TYPE_GROUP,
+                               'label' => $groupLabel
+                       );
+
+                       $shortcuts = $this->getShortcutsByGroup($groupId);
+                       $i = 0;
+                       foreach ($shortcuts as $shortcut) {
+                               $i++;
+                               $shortcutMenu[] = array(
+                                       'uid' => (int)$shortcut['raw']['uid'],
+                                       'groupid' => (int)$groupId,
+                                       'type' => static::TYPE_ITEM,
+                                       'action' => $shortcut['action'],
+                                       'icon' => $shortcut['icon'],
+                                       'label' => $shortcut['label']
+                               );
                        }
                }
-               $shortcutMenu[] = '</ul>';
 
-               if (count($shortcutMenu) == 2) {
+               $standaloneView = $this->getStandaloneView();
+               $standaloneView->assignMultiple(array(
+                       'hasEntries' => !empty($shortcutMenu),
+                       'shortcutMenu' => $shortcutMenu,
+                       'editIcon' => $editIcon,
+                       'deleteIcon' => $deleteIcon,
+               ));
+
+               if (empty($shortcutMenu)) {
                        // No shortcuts added yet, show a small help message how to add shortcuts
                        $title = $languageService->sL('LLL:EXT:lang/locallang_core.xlf:toolbarItems.bookmarks', TRUE);
                        $icon = IconUtility::getSpriteIcon('actions-system-shortcut-new', array(
                                'title' => $title
                        ));
                        $label = str_replace('%icon%', $icon, $languageService->sL('LLL:EXT:lang/locallang_misc.xlf:bookmarkDescription'));
-                       $compiledShortcutMenu = '<p>' . $label . '</p>';
-               } else {
-                       $compiledShortcutMenu = implode(LF, $shortcutMenu);
+
+                       $standaloneView->assign('introduction', $label);
                }
 
-               return $compiledShortcutMenu;
+               return $standaloneView->render();
        }
 
        /**
index f2e8685..f01b624 100644 (file)
@@ -29,9 +29,9 @@ use TYPO3\CMS\Core\Utility\StringUtility;
 class SystemInformationToolbarItem extends AbstractToolbarItem implements ToolbarItemInterface {
 
        /**
-        * Template file for the dropdown menu
+        * @var string Template file for the dropdown menu
         */
-       const TOOLBAR_MENU_TEMPLATE = 'SystemInformation.html';
+       protected $templateFile = 'SystemInformation.html';
 
        /**
         * Number displayed as badge on the dropdown trigger
@@ -280,14 +280,15 @@ class SystemInformationToolbarItem extends AbstractToolbarItem implements Toolba
                        return '';
                }
 
-               $this->getStandaloneView('backend')->assignMultiple(array(
+               $standaloneView = $this->getStandaloneView();
+               $standaloneView->assignMultiple(array(
                        'installToolUrl' => BackendUtility::getModuleUrl('system_InstallInstall'),
                        'messages' => $this->systemMessages,
                        'count' => $this->totalCount,
                        'severityBadgeClass' => $this->severityBadgeClass,
                        'systemInformation' => $this->systemInformation
                ));
-               return $this->getStandaloneView()->render();
+               return $standaloneView->render();
        }
 
        /**
index 406ac73..271fa26 100644 (file)
@@ -24,7 +24,12 @@ use TYPO3\CMS\Backend\Utility\BackendUtility;
 /**
  * User toolbar item
  */
-class UserToolbarItem implements ToolbarItemInterface {
+class UserToolbarItem extends AbstractToolbarItem implements ToolbarItemInterface {
+
+       /**
+        * @var string Template file for the dropdown menu
+        */
+       protected $templateFile = 'User.html';
 
        /**
         * Item is always enabled
@@ -75,7 +80,6 @@ class UserToolbarItem implements ToolbarItemInterface {
                $languageService = $this->getLanguageService();
 
                $dropdown = array();
-               $dropdown[] = '<ul class="dropdown-list">';
 
                /** @var BackendModuleRepository $backendModuleRepository */
                $backendModuleRepository = GeneralUtility::makeInstance(BackendModuleRepository::class);
@@ -84,34 +88,33 @@ class UserToolbarItem implements ToolbarItemInterface {
                if ($userModuleMenu != FALSE && $userModuleMenu->getChildren()->count() > 0) {
                        foreach ($userModuleMenu->getChildren() as $module) {
                                /** @var BackendModule $module */
-                               $dropdown[] ='<li'
-                                       . ' id="' . htmlspecialchars($module->getName()) . '"'
-                                       . ' class="typo3-module-menu-item submodule mod-' . htmlspecialchars($module->getName()) . '" '
-                                       . ' data-modulename="' . htmlspecialchars($module->getName()) . '"'
-                                       . ' data-navigationcomponentid="' . htmlspecialchars($module->getNavigationComponentId()) . '"'
-                                       . ' data-navigationframescript="' . htmlspecialchars($module->getNavigationFrameScript()) . '"'
-                                       . ' data-navigationframescriptparameters="' . htmlspecialchars($module->getNavigationFrameScriptParameters()) . '"'
-                                       . '>';
-                               $dropdown[] = '<a title="' . htmlspecialchars($module->getDescription()) . '" href="' . htmlspecialchars($module->getLink()) . '" class="dropdown-list-link modlink">';
-                               $dropdown[] = '<span class="submodule-icon typo3-app-icon"><span><span>' . $module->getIcon() . '</span></span></span>';
-                               $dropdown[] = '<span class="submodule-label">' . htmlspecialchars($module->getTitle()) . '</span>';
-                               $dropdown[] = '</a>';
-                               $dropdown[] = '</li>';
+                               $dropdown[] = array(
+                                       'id' => $module->getName(),
+                                       'navigation' => array(
+                                               'componentId' => $module->getNavigationComponentId(),
+                                               'frameScript' => $module->getNavigationFrameScript(),
+                                               'frameScriptParameters' => $module->getNavigationFrameScriptParameters(),
+                                       ),
+                                       'href' => $module->getLink(),
+                                       'description' => $module->getDescription(),
+                                       'icon' => $module->getIcon(),
+                                       'label' => $module->getTitle()
+                               );
                        }
-                       $dropdown[] = '<li class="divider"></li>';
                }
 
                // Logout button
-               $buttonLabel = 'LLL:EXT:lang/locallang_core.xlf:' . ($backendUser->user['ses_backuserid'] ? 'buttons.exit' : 'buttons.logout');
-               $dropdown[] = '<li class="reset-dropdown">';
-               $dropdown[] = '<a href="' . htmlspecialchars(BackendUtility::getModuleUrl('logout')) . '" class="btn btn-danger pull-right" target="_top"><i class="fa fa-power-off"></i> ';
-               $dropdown[] = $languageService->sL($buttonLabel, TRUE);
-               $dropdown[] = '</a>';
-               $dropdown[] = '</li>';
-
-               $dropdown[] = '</ul>';
-
-               return implode(LF, $dropdown);
+               $logoutButton = array(
+                       'label' => $languageService->sL('LLL:EXT:lang/locallang_core.xlf:' . ($backendUser->user['ses_backuserid'] ? 'buttons.exit' : 'buttons.logout')),
+                       'href' => htmlspecialchars(BackendUtility::getModuleUrl('logout')),
+               );
+
+               $standaloneView = $this->getStandaloneView();
+               $standaloneView->assignMultiple(array(
+                       'dropdown' => $dropdown,
+                       'logoutButton' => $logoutButton
+               ));
+               return $standaloneView->render();
        }
 
        /**
diff --git a/typo3/sysext/backend/Resources/Private/Templates/ToolbarMenu/ClearCache.html b/typo3/sysext/backend/Resources/Private/Templates/ToolbarMenu/ClearCache.html
new file mode 100644 (file)
index 0000000..e1a59d0
--- /dev/null
@@ -0,0 +1,9 @@
+<ul class="dropdown-list">
+       <f:for each="{items}" as="item">
+               <li>
+                       <a class="dropdown-list-link" href="{item.href}" title="{item.title}">
+                               <f:format.raw>{item.icon}</f:format.raw> {item.label}
+                       </a>
+               </li>
+       </f:for>
+</ul>
\ No newline at end of file
diff --git a/typo3/sysext/backend/Resources/Private/Templates/ToolbarMenu/Help.html b/typo3/sysext/backend/Resources/Private/Templates/ToolbarMenu/Help.html
new file mode 100644 (file)
index 0000000..a2b3450
--- /dev/null
@@ -0,0 +1,10 @@
+<ul class="dropdown-list">
+       <f:for each="{dropdown}" as="item">
+               <li class="typo3-module-menu-item submodule mod-{item.id}" id="{item.id}" data-modulename="{item.id}" data-navigationcomponentid="{item.navigation.componentId}" data-navigationframescript="{item.navigation.frameScript}"  data-navigationframescriptparameters="{item.navigation.frameScriptParameters}">
+                       <a class="dropdown-list-link modlink" href="{item.href}" title="{item.description}">
+                               <span class="submodule-icon typo3-app-icon"><span><span><f:format.raw>{item.icon}</f:format.raw></span></span></span>
+                               <span class="submodule-label">{item.label}</span>
+                       </a>
+               </li>
+       </f:for>
+</ul>
\ No newline at end of file
diff --git a/typo3/sysext/backend/Resources/Private/Templates/ToolbarMenu/Shortcut.html b/typo3/sysext/backend/Resources/Private/Templates/ToolbarMenu/Shortcut.html
new file mode 100644 (file)
index 0000000..3470370
--- /dev/null
@@ -0,0 +1,30 @@
+<f:if condition="{hasEntries}">
+       <f:then>
+               <ul class="dropdown-list">
+                       <f:for each="{shortcutMenu}" as="shortcut" iteration="iteration">
+                               <f:if condition="{shortcut.type} == 'group'">
+                                       <f:if condition="{iteration.isFirst}">
+                                               <f:then></f:then>
+                                               <f:else><li class="divider"></li></f:else>
+                                       </f:if>
+                                       <li class="dropdown-header" id="shortcut-group-{shortcut.uid}">
+                                               {shortcut.label}
+                                       </li>
+                               </f:if>
+
+                               <f:if condition="{shortcut.type} == 'item'">
+                                       <li class="shortcut" data-shortcutid="{shortcut.uid}">
+                                               <a class="dropdown-list-link dropdown-link-list-add-editdelete" href="#" onclick="{shortcut.action} return false;">
+                                                       <f:format.raw>{shortcut.icon}</f:format.raw> {shortcut.label}
+                                               </a>
+                                               <f:format.raw>{editIcon}</f:format.raw>
+                                               <f:format.raw>{deleteIcon}</f:format.raw>
+                                       </li>
+                               </f:if>
+                       </f:for>
+               </ul>
+       </f:then>
+       <f:else>
+               <f:format.raw>{introduction}</f:format.raw>
+       </f:else>
+</f:if>
\ No newline at end of file
diff --git a/typo3/sysext/backend/Resources/Private/Templates/ToolbarMenu/User.html b/typo3/sysext/backend/Resources/Private/Templates/ToolbarMenu/User.html
new file mode 100644 (file)
index 0000000..616add6
--- /dev/null
@@ -0,0 +1,16 @@
+<ul class="dropdown-list">
+       <f:for each="{dropdown}" as="item">
+               <li class="typo3-module-menu-item submodule mod-{item.id}" id="{item.id}" data-modulename="{item.id}" data-navigationcomponentid="{item.navigation.componentId}" data-navigationframescript="{item.navigation.frameScript}"  data-navigationframescriptparameters="{item.navigation.frameScriptParameters}">
+                       <a class="dropdown-list-link modlink" href="{item.href}" title="{item.description}">
+                               <span class="submodule-icon typo3-app-icon"><span><span><f:format.raw>{item.icon}</f:format.raw></span></span></span>
+                               <span class="submodule-label">{item.label}</span>
+                       </a>
+               </li>
+       </f:for>
+       <li class="divider"></li>
+       <li class="reset-dropdown">
+               <a href="{logoutButton.href}" class="btn btn-danger pull-right" target="_top">
+                       <i class="fa fa-power-off"></i> {logoutButton.label}
+               </a>
+       </li>
+</ul>
\ No newline at end of file
index 97f307b..67efa84 100644 (file)
@@ -15,16 +15,27 @@ namespace TYPO3\CMS\Opendocs\Backend\ToolbarItems;
  */
 
 use TYPO3\CMS\Backend\Toolbar\ToolbarItemInterface;
+use TYPO3\CMS\Backend\Backend\ToolbarItems\AbstractToolbarItem;
 use TYPO3\CMS\Backend\Utility\IconUtility;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
- * Alist of all open documents
+ * A list of all open documents
  *
  * @author Benjamin Mack <benni@typo3.org>
  * @author Ingo Renner <ingo@typo3.org>
  */
-class OpendocsToolbarItem implements ToolbarItemInterface {
+class OpendocsToolbarItem extends AbstractToolbarItem implements ToolbarItemInterface {
+
+       /**
+        * @var string Extension context
+        */
+       protected $extension = 'opendocs';
+
+       /**
+        * @var string Template file for the dropdown menu
+        */
+       protected $templateFile = 'Opendocs.html';
 
        /**
         * @var array
@@ -40,7 +51,8 @@ class OpendocsToolbarItem implements ToolbarItemInterface {
         * Constructor
         */
        public function __construct() {
-               $this->getLanguageService()->includeLLFile('EXT:opendocs/Resources/Private/Language/locallang.xlf');
+               parent::__construct();
+
                $this->loadDocsFromUserSession();
                $pageRenderer = $this->getPageRenderer();
                $pageRenderer->loadRequireJsModule('TYPO3/CMS/Opendocs/Toolbar/OpendocsMenu');
@@ -89,34 +101,40 @@ class OpendocsToolbarItem implements ToolbarItemInterface {
         * @return string HTML
         */
        public function getDropDown() {
-               $languageService = $this->getLanguageService();
                $openDocuments = $this->openDocs;
                $recentDocuments = $this->recentDocs;
-               $entries = array();
-               if (count($openDocuments)) {
-                       $entries[] = '<li class="dropdown-header">' . $languageService->getLL('open_docs', TRUE) . '</li>';
+               $entries = array(
+                       'open' => array(),
+                       'recent' => array()
+               );
+               if (!empty($openDocuments)) {
                        $i = 0;
                        foreach ($openDocuments as $md5sum => $openDocument) {
                                $i++;
-                               $entries[] = $this->renderMenuEntry($openDocument, $md5sum, FALSE, $i == 1);
+                               $entry = $this->renderMenuEntry($openDocument, $md5sum, FALSE, $i === 1);
+                               if (!empty($entry)) {
+                                       $entries['open'][] = $entry;
+                               }
                        }
-                       $entries[] = '<li class="divider"></li>';
                }
                // If there are "recent documents" in the list, add them
-               if (count($recentDocuments)) {
-                       $entries[] = '<li class="dropdown-header">' . $languageService->getLL('recent_docs', TRUE) . '</li>';
+               if (!empty($recentDocuments)) {
                        $i = 0;
                        foreach ($recentDocuments as $md5sum => $recentDocument) {
                                $i++;
-                               $entries[] = $this->renderMenuEntry($recentDocument, $md5sum, TRUE, $i == 1);
+                               $entry = $this->renderMenuEntry($recentDocument, $md5sum, TRUE, $i === 1);
+                               if (!empty($entry)) {
+                                       $entries['recent'][] = $entry;
+                               }
                        }
                }
-               if (count($entries)) {
-                       $content = '<ul class="dropdown-list">' . implode('', $entries) . '</ul>';
-               } else {
-                       $content = '<p>' . $languageService->getLL('no_docs', TRUE) . '</p>';
-               }
-               return $content;
+
+               $standaloneView = $this->getStandaloneView();
+               $standaloneView->assignMultiple(array(
+                       'entries' => $entries,
+                       'hasEntries' => !empty($entries['open']) || !empty($entries['recent'])
+               ));
+               return $standaloneView->render();
        }
 
        /**
@@ -136,7 +154,7 @@ class OpendocsToolbarItem implements ToolbarItemInterface {
                        // Record seems to be deleted
                        return '';
                }
-               $label = htmlspecialchars(strip_tags(htmlspecialchars_decode($document[0])));
+               $label = strip_tags(htmlspecialchars_decode($document[0]));
                $icon = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIconForRecord($table, $record);
                $link = \TYPO3\CMS\Backend\Utility\BackendUtility::getModuleUrl('record_edit') . '&' . $document[2];
                $pageId = (int)$document[3]['uid'];
@@ -148,17 +166,21 @@ class OpendocsToolbarItem implements ToolbarItemInterface {
                        $title = $this->getLanguageService()->sL('LLL:EXT:lang/locallang_core.xlf:rm.closeDoc', TRUE);
                        // Open document
                        $closeIcon = \TYPO3\CMS\Backend\Utility\IconUtility::getSpriteIcon('actions-document-close');
-                       $entry = '
-                               <li class="opendoc">
-                                       <a href="#" class="dropdown-list-link dropdown-link-list-add-close" onclick="' . htmlspecialchars($onClickCode) . '" target="content">' . $icon . ' ' . $label . '</a>
-                                       <a href="#" class="dropdown-list-link-close" data-opendocsidentifier="' . $md5sum . '" title="' . $title . '">' . $closeIcon . '</a>
-                               </li>';
+                       $entry = array(
+                               'onclick' => $onClickCode,
+                               'icon' => $icon,
+                               'label' => $label,
+                               'md5sum' => $md5sum,
+                               'title' => $title,
+                               'closeIcon' => $closeIcon
+                       );
                } else {
                        // Recently used document
-                       $entry = '
-                               <li>
-                                       <a href="#" class="dropdown-list-link" onclick="' . htmlspecialchars($onClickCode) . '" target="content">' . $icon . ' ' . $label . '</a>
-                               </li>';
+                       $entry = array(
+                               'onclick' => $onClickCode,
+                               'icon' => $icon,
+                               'label' => $label
+                       );
                }
                return $entry;
        }
diff --git a/typo3/sysext/opendocs/Resources/Private/Templates/ToolbarMenu/Opendocs.html b/typo3/sysext/opendocs/Resources/Private/Templates/ToolbarMenu/Opendocs.html
new file mode 100644 (file)
index 0000000..cd73981
--- /dev/null
@@ -0,0 +1,45 @@
+<f:if condition="{hasEntries}">
+       <f:then>
+               <ul class="dropdown-list">
+                       <f:for each="{entries.open}" as="entry" iteration="iteration">
+                               <f:if condition="{iteration.isFirst}">
+                                       <li class="dropdown-header"><f:translate key="open_docs" /></li>
+                               </f:if>
+                               <li class="opendoc">
+                                       <a href="#" class="dropdown-list-link dropdown-link-list-add-close" onclick="{entry.onclick}" target="content">
+                                               <f:format.raw>{entry.icon}</f:format.raw> {entry.label}
+                                       </a>
+                                       <a href="#" class="dropdown-list-link-close" data-opendocsidentifier="{entry.md5sum}" title="{entry.title}">
+                                               <f:format.raw>{entry.closeIcon}</f:format.raw>
+                                       </a>
+                               </li>
+                               <f:if condition="isLast">
+                                       <f:then></f:then>
+                                       <f:else>
+                                               <li class="divider"></li>
+                                       </f:else>
+                               </f:if>
+                       </f:for>
+
+                       <f:for each="{entries.recent}" as="entry" iteration="iteration">
+                               <f:if condition="{iteration.isFirst}">
+                                       <li class="dropdown-header"><f:translate key="recent_docs" /></li>
+                               </f:if>
+                               <li>
+                                       <a href="#" class="dropdown-list-link" onclick="{entry.onclick}" target="content">
+                                               <f:format.raw>{entry.icon}</f:format.raw> {entry.label}
+                                       </a>
+                               </li>
+                               <f:if condition="isLast">
+                                       <f:then></f:then>
+                                       <f:else>
+                                               <li class="divider"></li>
+                                       </f:else>
+                               </f:if>
+                       </f:for>
+               </ul>
+       </f:then>
+       <f:else>
+               <p><f:translate key="no_docs" /></p>
+       </f:else>
+</f:if>
index 64d7343..fb79c3b 100644 (file)
@@ -16,6 +16,7 @@ namespace TYPO3\CMS\Workspaces\Backend\ToolbarItems;
 
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Backend\Toolbar\ToolbarItemInterface;
+use TYPO3\CMS\Backend\Backend\ToolbarItems\AbstractToolbarItem;
 use TYPO3\CMS\Workspaces\Service\WorkspaceService;
 use TYPO3\CMS\Backend\Utility\IconUtility;
 
@@ -24,7 +25,17 @@ use TYPO3\CMS\Backend\Utility\IconUtility;
  *
  * @author Ingo Renner <ingo@typo3.org>
  */
-class WorkspaceSelectorToolbarItem implements ToolbarItemInterface {
+class WorkspaceSelectorToolbarItem extends AbstractToolbarItem implements ToolbarItemInterface {
+
+       /**
+        * @var string Extension context
+        */
+       protected $extension = 'workspaces';
+
+       /**
+        * @var string Template file for the dropdown menu
+        */
+       protected $templateFile = 'WorkspaceSelector.html';
 
        /**
         * @var array
@@ -35,7 +46,9 @@ class WorkspaceSelectorToolbarItem implements ToolbarItemInterface {
         * Constructor
         */
        public function __construct() {
-               /** @var \TYPO3\CMS\Workspaces\Service\WorkspaceService $wsService */
+               parent::__construct();
+
+               /** @var WorkspaceService $wsService */
                $wsService = GeneralUtility::makeInstance(WorkspaceService::class);
                $this->availableWorkspaces = $wsService->getAvailableWorkspaces();
 
@@ -95,36 +108,40 @@ class WorkspaceSelectorToolbarItem implements ToolbarItemInterface {
                foreach ($this->availableWorkspaces as $workspaceId => $label) {
                        $workspaceId = (int)$workspaceId;
                        $iconState = ($workspaceId === $activeWorkspace ? $stateCheckedIcon : $stateUncheckedIcon);
-                       $classValue = ($workspaceId === $activeWorkspace ? ' class="selected"' : '');
+                       $classValue = ($workspaceId === $activeWorkspace ? 'selected' : '');
                        $sectionName = ($index++ === 0 ? 'top' : 'items');
-                       $workspaceSections[$sectionName][] = '<li' . $classValue . '>'
-                               . '<a href="backend.php?changeWorkspace=' . $workspaceId . '" data-workspaceid="' . $workspaceId . '" class="dropdown-list-link tx-workspaces-switchlink">'
-                               . $iconState . ' ' . htmlspecialchars($label)
-                               . '</a></li>';
+                       $workspaceSections[$sectionName][] = array(
+                               'href' => 'backend.php?changeWorkspace=' . $workspaceId,
+                               'class' => $classValue,
+                               'wsid' => $workspaceId,
+                               'icon' => $iconState,
+                               'label' => $label
+                       );
                }
 
                if (!empty($workspaceSections['top'])) {
                        // Add the "Go to workspace module" link
                        // if there is at least one icon on top and if the access rights are there
                        if ($backendUser->check('modules', 'web_WorkspacesWorkspaces')) {
-                               $workspaceSections['top'][] = '<li><a target="content" data-module="web_WorkspacesWorkspaces" class="dropdown-list-link tx-workspaces-modulelink">'
-                                       . $stateUncheckedIcon . ' ' . $languageService->getLL('bookmark_workspace', TRUE)
-                                       . '</a></li>';
+                               $workspaceSections['top'][] = array(
+                                       'module' => 'web_WorkspacesWorkspaces',
+                                       'icon' => $stateUncheckedIcon,
+                                       'label' => $languageService->getLL('bookmark_workspace', TRUE)
+                               );
                        }
                } else {
                        // no items on top (= no workspace to work in)
-                       $workspaceSections['top'][] = '<li>' . $stateUncheckedIcon . ' ' . $languageService->getLL('bookmark_noWSfound', TRUE) . '</li>';
+                       $workspaceSections['top'][] = array(
+                               'icon' => $stateUncheckedIcon,
+                               'label' => $languageService->getLL('bookmark_noWSfound', TRUE)
+                       );
                }
 
-               $workspaceMenu = array(
-                       '<ul class="dropdown-list">' ,
-                               implode(LF, $workspaceSections['top']),
-                               (!empty($workspaceSections['items']) ? '<li class="divider"></li>' : ''),
-                               implode(LF, $workspaceSections['items']),
-                       '</ul>'
-               );
-
-               return implode(LF, $workspaceMenu);
+               $standaloneView = $this->getStandaloneView();
+               $standaloneView->assignMultiple(array(
+                       'workspaceSections' => $workspaceSections
+               ));
+               return $standaloneView->render();
        }
 
        /**
diff --git a/typo3/sysext/workspaces/Resources/Private/Templates/ToolbarMenu/WorkspaceSelector.html b/typo3/sysext/workspaces/Resources/Private/Templates/ToolbarMenu/WorkspaceSelector.html
new file mode 100644 (file)
index 0000000..d1b82c0
--- /dev/null
@@ -0,0 +1,32 @@
+<ul class="dropdown-list">
+       <f:for each="{workspaceSections}" key="sectionKey" as="section">
+               <f:for each="{section}" as="item" iteration="iteration">
+                       <f:if condition="{sectionKey} == 'items'">
+                               <f:if condition="{iteration.isFirst}">
+                                       <li class="divider"></li>
+                               </f:if>
+                       </f:if>
+                       <li class="{item.class}">
+                               <f:if condition="{item.href}">
+                                       <f:then>
+                                               <a href="{item.href}" data-workspaceid="{item.wsid}" class="dropdown-list-link tx-workspaces-switchlink">
+                                                       <f:format.raw>{item.icon}</f:format.raw> {item.label}
+                                               </a>
+                                       </f:then>
+                                       <f:else>
+                                               <f:if condition="{item.module}">
+                                                       <f:then>
+                                                               <a target="content" data-module="{item.module}" class="dropdown-list-link tx-workspaces-modulelink">
+                                                                       <f:format.raw>{item.icon}</f:format.raw> {item.label}
+                                                               </a>
+                                                       </f:then>
+                                                       <f:else>
+                                                               <f:format.raw>{item.icon}</f:format.raw> {item.label}
+                                                       </f:else>
+                                               </f:if>
+                                       </f:else>
+                               </f:if>
+                       </li>
+               </f:for>
+       </f:for>
+</ul>
\ No newline at end of file