From dc790e93a81f68071137a618aadfe33d8b5c9697 Mon Sep 17 00:00:00 2001 From: Patrick Kollodzik <patrick.kollodzik@gmail.com> Date: Sat, 3 Sep 2016 00:27:43 +0200 Subject: [PATCH] [TASK] Fluidification of ShortcutToolbarItem Because the ShortcutToolbarItem has three different actions, every action has its own template. Resolves: #77800 Releases: master Change-Id: I054569376a0a5f62bb40e7d77f675350e0464423 Reviewed-on: https://review.typo3.org/49810 Tested-by: TYPO3com <no-reply@typo3.com> Reviewed-by: Alexander Stehlik <alexander.stehlik@gmail.com> Tested-by: Alexander Stehlik <alexander.stehlik@gmail.com> Reviewed-by: Joerg Boesche <typo3@joergboesche.de> Reviewed-by: Susanne Moog <susanne.moog@typo3.org> Tested-by: Susanne Moog <susanne.moog@typo3.org> --- .../ToolbarItems/ShortcutToolbarItem.php | 161 +++++++----------- .../ShortcutToolbarItem/Shortcut.html | 31 ++++ .../ShortcutToolbarItem/DropDown.html | 33 ++++ .../ShortcutToolbarItem/EditForm.html | 19 +++ .../Templates/ShortcutToolbarItem/Item.html | 7 + .../Private/Language/locallang_misc.xlf | 2 +- 6 files changed, 154 insertions(+), 99 deletions(-) create mode 100644 typo3/sysext/backend/Resources/Private/Partials/ShortcutToolbarItem/Shortcut.html create mode 100644 typo3/sysext/backend/Resources/Private/Templates/ShortcutToolbarItem/DropDown.html create mode 100644 typo3/sysext/backend/Resources/Private/Templates/ShortcutToolbarItem/EditForm.html create mode 100644 typo3/sysext/backend/Resources/Private/Templates/ShortcutToolbarItem/Item.html diff --git a/typo3/sysext/backend/Classes/Backend/ToolbarItems/ShortcutToolbarItem.php b/typo3/sysext/backend/Classes/Backend/ToolbarItems/ShortcutToolbarItem.php index cf8151999c21..e089707d2ad6 100644 --- a/typo3/sysext/backend/Classes/Backend/ToolbarItems/ShortcutToolbarItem.php +++ b/typo3/sysext/backend/Classes/Backend/ToolbarItems/ShortcutToolbarItem.php @@ -29,6 +29,7 @@ use TYPO3\CMS\Core\Resource\Exception\ResourceDoesNotExistException; use TYPO3\CMS\Core\Resource\ResourceFactory; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\MathUtility; +use TYPO3\CMS\Fluid\View\StandaloneView; /** * Class to render the shortcut menu @@ -127,79 +128,37 @@ class ShortcutToolbarItem implements ToolbarItemInterface * Render shortcut icon * * @return string HTML + * @throws \TYPO3\CMS\Extbase\Mvc\Exception\InvalidExtensionNameException + * @throws \InvalidArgumentException */ public function getItem() { - $title = htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:toolbarItems.bookmarks')); - $icon = $this->iconFactory->getIcon('apps-toolbar-menu-shortcut', Icon::SIZE_SMALL)->render('inline'); - return ' - <span class="toolbar-item-icon" title="' . $title . '">' . $icon . '</span> - <span class="toolbar-item-title">' . $title . '</span> - '; + return $this->getFluidTemplateObject('Item.html')->render(); } /** * Render drop down content * * @return string HTML + * @throws \TYPO3\CMS\Extbase\Mvc\Exception\InvalidExtensionNameException + * @throws \InvalidArgumentException */ public function getDropDown() { - $languageService = $this->getLanguageService(); - $shortcutEdit = htmlspecialchars($languageService->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:toolbarItems.bookmarksEdit')); - $shortcutDelete = htmlspecialchars($languageService->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:toolbarItems.bookmarksDelete')); - $editIcon = '<a href="#" class="dropdown-table-actions-btn dropdown-table-actions-btn-edit t3js-shortcut-edit" title="' . $shortcutEdit . '">' - . $this->iconFactory->getIcon('actions-open', Icon::SIZE_SMALL)->render('inline') . '</a>'; - $deleteIcon = '<a href="#" class="dropdown-table-actions-btn dropdown-table-actions-btn-delete t3js-shortcut-delete" title="' . $shortcutDelete . '">' - . $this->iconFactory->getIcon('actions-delete', Icon::SIZE_SMALL)->render('inline') . '</a>'; - $shortcutMenu = []; - $shortcutMenu[] = '<h3 class="dropdown-headline">' . htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:toolbarItems.bookmarks')) . '</h3>'; - $shortcutMenu[] = '<hr>'; - - // Render groups and the contained shortcuts $groups = $this->getGroupsFromShortcuts(); - $groupCount = 0; arsort($groups, SORT_NUMERIC); foreach ($groups as $groupId => $groupLabel) { - $shortcuts = $this->getShortcutsByGroup($groupId); - if (count($shortcuts) > 0) { - if ($groupCount !== 0) { - $shortcutMenu[] = '<hr>'; - } - $groupCount++; - if ($groupLabel) { - $shortcutMenu[] = '<h3 class="dropdown-headline" id="shortcut-group-' . (int)$groupId . '">' . $groupLabel . '</h3>'; - } - $shortcutMenu[] = '<div class="dropdown-table" data-shortcutgroup="' . (int)$groupId . '">'; - foreach ($shortcuts as $shortcut) { - $shortcutItem = '<div class="dropdown-table-row t3js-topbar-shortcut" data-shortcutid="' . (int)$shortcut['raw']['uid'] . '" data-shortcutgroup="' . (int)$groupId . '">'; - $shortcutItem .= '<div class="dropdown-table-column dropdown-table-icon">'; - $shortcutItem .= $shortcut['icon']; - $shortcutItem .= '</div>'; - $shortcutItem .= '<div class="dropdown-table-column dropdown-table-title">'; - $shortcutItem .= '<a class="dropdown-table-title-ellipsis" href="#" onclick="' . htmlspecialchars($shortcut['action']) . ' return false;">'; - $shortcutItem .= htmlspecialchars($shortcut['label']); - $shortcutItem .= '</a>'; - $shortcutItem .= '</div>'; - $shortcutItem .= '<div class="dropdown-table-column dropdown-table-actions">' . $editIcon . $deleteIcon . '</div>'; - $shortcutItem .= '</div>'; - $shortcutMenu[] = $shortcutItem; - } - $shortcutMenu[] = '</div>'; - } + $shortcutMenu[] = [ + 'id' => (int)$groupId, + 'title' => $groupLabel, + 'shortcuts' => $this->getShortcutsByGroup($groupId) + ]; } - $compiledShortcutMenu = implode(LF, $shortcutMenu); - if (count($shortcutMenu) === 2) { - // No shortcuts added yet, show a small help message how to add shortcuts - $title = htmlspecialchars($languageService->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:toolbarItems.bookmarks')); - $icon = '<span title="' . $title . '">' . $this->iconFactory->getIcon('actions-system-shortcut-new', Icon::SIZE_SMALL)->render('inline') . '</span>'; - $label = str_replace('%icon%', $icon, htmlspecialchars($languageService->sL('LLL:EXT:lang/Resources/Private/Language/locallang_misc.xlf:bookmarkDescription'))); - $compiledShortcutMenu .= '<p>' . $label . '</p>'; - } - - return $compiledShortcutMenu; + $dropDownView = $this->getFluidTemplateObject('DropDown.html'); + $dropDownView->assign('shortcutMenu', $shortcutMenu); + return $dropDownView->render(); } /** @@ -476,6 +435,7 @@ class ShortcutToolbarItem implements ToolbarItemInterface } $this->shortcutGroups[$groupId] = $label; } + return $this->shortcutGroups; } @@ -485,17 +445,18 @@ class ShortcutToolbarItem implements ToolbarItemInterface * @param ServerRequestInterface $request * @param ResponseInterface $response * @return ResponseInterface the full HTML for the form + * @throws \TYPO3\CMS\Extbase\Mvc\Exception\InvalidExtensionNameException + * @throws \RuntimeException + * @throws \InvalidArgumentException */ public function editFormAction(ServerRequestInterface $request, ResponseInterface $response) { - $languageService = $this->getLanguageService(); $parsedBody = $request->getParsedBody(); $queryParams = $request->getQueryParams(); - $selectedShortcutId = (int)(isset($parsedBody['shortcutId']) ? $parsedBody['shortcutId'] : $queryParams['shortcutId']); - $selectedShortcutGroupId = (int)(isset($parsedBody['shortcutGroup']) ? $parsedBody['shortcutGroup'] : $queryParams['shortcutGroup']); + $selectedShortcutId = (int)($parsedBody['shortcutId'] ?? $queryParams['shortcutId']); + $selectedShortcutGroupId = (int)($parsedBody['shortcutGroup'] ?? $queryParams['shortcutGroup']); $selectedShortcut = $this->getShortcutById($selectedShortcutId); - $shortcutGroups = $this->shortcutGroups; if (!$this->getBackendUser()->isAdmin()) { foreach ($shortcutGroups as $groupId => $groupName) { @@ -505,33 +466,14 @@ class ShortcutToolbarItem implements ToolbarItemInterface } } - // build the form - $content = ' - <form class="shortcut-form" role="form" data-shortcutid="' . (int)$selectedShortcutId . '"> - <h3 class="dropdown-headline"> - ' . htmlspecialchars($languageService->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:toolbarItems.bookmarksEdit')) . ' - </h3> - <hr> - <div class="form-group"> - <input type="text" class="form-control" name="shortcut-title" value="' . htmlspecialchars($selectedShortcut['label']) . '"> - </div>'; - $content .= ' - <div class="form-group"> - <select class="form-control" name="shortcut-group">'; - foreach ($shortcutGroups as $shortcutGroupId => $shortcutGroupTitle) { - $content .= '<option value="' . (int)$shortcutGroupId . '"' . ($selectedShortcutGroupId == $shortcutGroupId ? ' selected="selected"' : '') . '>' . htmlspecialchars($shortcutGroupTitle) . '</option>'; - } - $content .= ' - </select> - </div> - <hr> - <input type="button" class="btn btn-default shortcut-form-cancel" value="Cancel"> - <input type="button" class="btn btn-success shortcut-form-save" value="Save"> - </form>'; - - $response->getBody()->write($content); - $response = $response->withHeader('Content-Type', 'text/html; charset=utf-8'); - return $response; + $editFormView = $this->getFluidTemplateObject('EditForm.html'); + $editFormView->assign('selectedShortcutId', $selectedShortcutId); + $editFormView->assign('selectedShortcutGroupId', $selectedShortcutGroupId); + $editFormView->assign('selectedShortcut', $selectedShortcut); + $editFormView->assign('shortcutGroups', $shortcutGroups); + + $response->getBody()->write($editFormView->render()); + return $response->withHeader('Content-Type', 'text/html; charset=utf-8'); } /** @@ -660,6 +602,7 @@ class ShortcutToolbarItem implements ToolbarItemInterface * @param string $url * @param string $shortcutName * @return ResponseInterface + * @throws \InvalidArgumentException */ protected function tryAddingTheShortcut(ResponseInterface $response, $url, $shortcutName) { @@ -675,8 +618,7 @@ class ShortcutToolbarItem implements ToolbarItemInterface } $response->getBody()->write($shortcutCreated); - $response = $response->withHeader('Content-Type', 'text/html; charset=utf-8'); - return $response; + return $response->withHeader('Content-Type', 'text/html; charset=utf-8'); } /** @@ -843,22 +785,21 @@ class ShortcutToolbarItem implements ToolbarItemInterface * @param array $row * @param array $shortcut * @return string Shortcut icon as img tag + * @throws \InvalidArgumentException */ protected function getShortcutIcon($row, $shortcut) { - $languageService = $this->getLanguageService(); - $titleAttribute = htmlspecialchars($languageService->sL('LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:toolbarItems.shortcut')); switch ($row['module_name']) { case 'xMOD_alt_doc.php': $table = $shortcut['table']; $recordid = $shortcut['recordid']; $icon = ''; - if ($shortcut['type'] == 'edit') { + if ($shortcut['type'] === 'edit') { // Creating the list of fields to include in the SQL query: $selectFields = $this->fieldArray; $selectFields[] = 'uid'; $selectFields[] = 'pid'; - if ($table == 'pages') { + if ($table === 'pages') { $selectFields[] = 'module'; $selectFields[] = 'extendToSubpages'; $selectFields[] = 'doktype'; @@ -893,16 +834,16 @@ class ShortcutToolbarItem implements ToolbarItemInterface $row = $queryBuilder->execute()->fetch(); - $icon = '<span title="' . $titleAttribute . '">' . $this->iconFactory->getIconForRecord($table, (array)$row, Icon::SIZE_SMALL)->render() . '</span>'; - } elseif ($shortcut['type'] == 'new') { - $icon = '<span title="' . $titleAttribute . '">' . $this->iconFactory->getIconForRecord($table, [], Icon::SIZE_SMALL)->render() . '</span>'; + $icon = $this->iconFactory->getIconForRecord($table, (array)$row, Icon::SIZE_SMALL)->render(); + } elseif ($shortcut['type'] === 'new') { + $icon = $this->iconFactory->getIconForRecord($table, [], Icon::SIZE_SMALL)->render(); } break; case 'file_edit': - $icon = '<span title="' . $titleAttribute . '">' . $this->iconFactory->getIcon('mimetypes-text-html', Icon::SIZE_SMALL)->render() . '</span>'; + $icon = $this->iconFactory->getIcon('mimetypes-text-html', Icon::SIZE_SMALL)->render(); break; case 'wizard_rte': - $icon = '<span title="' . $titleAttribute . '">' . $this->iconFactory->getIcon('mimetypes-word', Icon::SIZE_SMALL)->render() . '</span>'; + $icon = $this->iconFactory->getIcon('mimetypes-word', Icon::SIZE_SMALL)->render(); break; default: $iconIdentifier = ''; @@ -916,8 +857,9 @@ class ShortcutToolbarItem implements ToolbarItemInterface if (!$iconIdentifier) { $iconIdentifier = 'empty-empty'; } - $icon = '<span title="' . $titleAttribute . '">' . $this->iconFactory->getIcon($iconIdentifier, Icon::SIZE_SMALL)->render() . '</span>'; + $icon = $this->iconFactory->getIcon($iconIdentifier, Icon::SIZE_SMALL)->render(); } + return $icon; } @@ -1000,4 +942,27 @@ class ShortcutToolbarItem implements ToolbarItemInterface { return $GLOBALS['LANG']; } + + /** + * returns a new standalone view, shorthand function + * + * @param string $templateFilename + * @return StandaloneView + * @throws \TYPO3\CMS\Extbase\Mvc\Exception\InvalidExtensionNameException + * @throws \InvalidArgumentException + * @internal param string $templateFile + */ + protected function getFluidTemplateObject(string $templateFilename) + { + /** @var StandaloneView $view */ + $view = GeneralUtility::makeInstance(StandaloneView::class); + $view->setLayoutRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Layouts')]); + $view->setPartialRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Partials')]); + $view->setTemplateRootPaths([GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Templates')]); + + $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName('EXT:backend/Resources/Private/Templates/ShortcutToolbarItem/' . $templateFilename)); + + $view->getRequest()->setControllerExtensionName('Backend'); + return $view; + } } diff --git a/typo3/sysext/backend/Resources/Private/Partials/ShortcutToolbarItem/Shortcut.html b/typo3/sysext/backend/Resources/Private/Partials/ShortcutToolbarItem/Shortcut.html new file mode 100644 index 000000000000..501c48febf7b --- /dev/null +++ b/typo3/sysext/backend/Resources/Private/Partials/ShortcutToolbarItem/Shortcut.html @@ -0,0 +1,31 @@ +{namespace core = TYPO3\CMS\Core\ViewHelpers} +<div class="dropdown-table-row t3js-topbar-shortcut" data-shortcutid="{shortcut.raw.uid}" data-shortcutgroup="{group.id}"> + <div class="dropdown-table-column dropdown-table-icon"> + <span title="{f:translate(key: 'LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:toolbarItems.shortcut')}"> + <f:format.raw>{shortcut.icon}</f:format.raw> + </span> + </div> + <div class="dropdown-table-column dropdown-table-title"> + <f:link.external uri="#" class="dropdown-table-title-ellipsis" onclick="{shortcut.action} return false;" defaultScheme="">{shortcut.label}</f:link.external> + </div> + <div class="dropdown-table-column dropdown-table-actions"> + <f:render section="Edit"/> + <f:render section="Delete"/> + </div> +</div> + +<f:section name="Edit"> + <f:link.external uri="#" class="dropdown-table-actions-btn dropdown-table-actions-btn-edit t3js-shortcut-edit" + title="{f:translate(key: 'LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:toolbarItems.bookmarksEdit')}" + defaultScheme=""> + <core:icon identifier="actions-open" alternativeMarkupIdentifier="inline"/> + </f:link.external> +</f:section> + +<f:section name="Delete"> + <f:link.external uri="#" class="dropdown-table-actions-btn dropdown-table-actions-btn-delete t3js-shortcut-delete" + title="{f:translate(key: 'LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:toolbarItems.bookmarksDelete')}" + defaultScheme=""> + <core:icon identifier="actions-delete" alternativeMarkupIdentifier="inline"/> + </f:link.external> +</f:section> diff --git a/typo3/sysext/backend/Resources/Private/Templates/ShortcutToolbarItem/DropDown.html b/typo3/sysext/backend/Resources/Private/Templates/ShortcutToolbarItem/DropDown.html new file mode 100644 index 000000000000..2754bc6be705 --- /dev/null +++ b/typo3/sysext/backend/Resources/Private/Templates/ShortcutToolbarItem/DropDown.html @@ -0,0 +1,33 @@ +{namespace core = TYPO3\CMS\Core\ViewHelpers} +<h3 class="dropdown-headline"> + {f:translate(key: 'LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:toolbarItems.bookmarks')} +</h3> +<hr> +<f:if condition="{f:count(subject: '{shortcutMenu}')} == 0"> + <f:then> + <f:render section="helpMessage"/> + </f:then> + <f:else> + <f:for each="{shortcutMenu}" as="group" iteration="iterator"> + <f:if condition="!{iterator.isFirst}"> + <hr> + </f:if> + <f:if condition="{group.title}"> + <h3 class="dropdown-headline" id="shortcut-group-{group.id}">{group.title}</h3> + </f:if> + <div class="dropdown-table" data-shortcutgroup="{group.id}"> + <f:for each="{group.shortcuts}" as="shortcut"> + <f:render partial="ShortcutToolbarItem/Shortcut" arguments="{group : group, shortcut : shortcut}" /> + </f:for> + </div> + </f:for> + </f:else> +</f:if> + +<f:section name="helpMessage"> + <f:comment>No shortcuts added yet, show a small help message how to add shortcuts</f:comment> + <f:alias + map="{inlineIcon: '{core:icon(identifier: \'actions-system-shortcut-new\', alternativeMarkupIdentifier: \'inline\')}', inlineIconTitle: '{f:translate(key: \'LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:toolbarItems.bookmarks\')}'}"> + <p>{f:translate(key: 'LLL:EXT:lang/Resources/Private/Language/locallang_misc.xlf:bookmarkDescription', arguments:'{0: \'<span title="{inlineIconTitle}">{inlineIcon -> f:format.raw()}</span>\'}') -> f:format.raw()}</p> + </f:alias> +</f:section> diff --git a/typo3/sysext/backend/Resources/Private/Templates/ShortcutToolbarItem/EditForm.html b/typo3/sysext/backend/Resources/Private/Templates/ShortcutToolbarItem/EditForm.html new file mode 100644 index 000000000000..9a6728375cdc --- /dev/null +++ b/typo3/sysext/backend/Resources/Private/Templates/ShortcutToolbarItem/EditForm.html @@ -0,0 +1,19 @@ +<form class="shortcut-form" role="form" data-shortcutid="{selectedShortcutId}"> + <h3 class="dropdown-headline"> + {f:translate(key: 'LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:toolbarItems.bookmarksEdit')} + </h3> + <hr> + <div class="form-group"> + <input type="text" class="form-control" name="shortcut-title" value="{selectedShortcut.label}"/> + </div> + <div class="form-group"> + <select class="form-control" name="shortcut-group"> + <f:for each="{shortcutGroups}" key="shortcutGroupId" as="shortcutGroupTitle"> + <option value="{shortcutGroupId}" {f:if(condition: '{selectedShortcutGroupId} == {shortcutGroupId}', then: 'selected="selected"')}>{shortcutGroupTitle}</option> + </f:for> + </select> + </div> + <hr> + <input type="button" class="btn btn-default shortcut-form-cancel" value="Cancel"/> + <input type="button" class="btn btn-success shortcut-form-save" value="Save"/> +</form> diff --git a/typo3/sysext/backend/Resources/Private/Templates/ShortcutToolbarItem/Item.html b/typo3/sysext/backend/Resources/Private/Templates/ShortcutToolbarItem/Item.html new file mode 100644 index 000000000000..9cf9b95a527a --- /dev/null +++ b/typo3/sysext/backend/Resources/Private/Templates/ShortcutToolbarItem/Item.html @@ -0,0 +1,7 @@ +{namespace core = TYPO3\CMS\Core\ViewHelpers} +<span class="toolbar-item-icon" title="{f:translate(key: 'LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:toolbarItems.bookmarks')}"> + <core:icon identifier="apps-toolbar-menu-shortcut" alternativeMarkupIdentifier="inline" /> +</span> +<span class="toolbar-item-title"> + <f:translate key="LLL:EXT:lang/Resources/Private/Language/locallang_core.xlf:toolbarItems.bookmarks"/> +</span> diff --git a/typo3/sysext/lang/Resources/Private/Language/locallang_misc.xlf b/typo3/sysext/lang/Resources/Private/Language/locallang_misc.xlf index afed89ddf837..291a1a4e7507 100644 --- a/typo3/sysext/lang/Resources/Private/Language/locallang_misc.xlf +++ b/typo3/sysext/lang/Resources/Private/Language/locallang_misc.xlf @@ -91,7 +91,7 @@ <source>Go to Workspace Module</source> </trans-unit> <trans-unit id="bookmarkDescription"> - <source>This is the bookmarks menu. You do not have any bookmarks added yet, you can do so by clicking the bookmark icon %icon%, which you can find on each page in the backend.</source> + <source>This is the bookmarks menu. You do not have any bookmarks added yet, you can do so by clicking the bookmark icon %s, which you can find on each page in the backend.</source> </trans-unit> <trans-unit id="bookmark_edit"> <source>Edit</source> -- GitLab