Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions Classes/EventListener/ModifyPageLayoutContentEventListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace B13\Collapse\EventListener;

use TYPO3\CMS\Backend\Controller\Event\ModifyPageLayoutContentEvent;
use TYPO3\CMS\Core\Page\PageRenderer;

final class ModifyPageLayoutContentEventListener
{
public function __construct(private readonly PageRenderer $pageRenderer)
{
}

public function __invoke(ModifyPageLayoutContentEvent $event): void
{
$this->pageRenderer->loadJavaScriptModule('@b13/collapse/PageModuleCollapse.js');
}
}
77 changes: 0 additions & 77 deletions Classes/PageModuleModifier.php

This file was deleted.

74 changes: 74 additions & 0 deletions Classes/ViewHelpers/CollapseViewHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

declare(strict_types=1);

namespace B13\Collapse\ViewHelpers;

use B13\Container\Backend\Grid\ContainerGridColumnItem;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Backend\View\BackendLayout\Grid\AbstractGridObject;
use TYPO3\CMS\Backend\View\BackendLayout\Grid\GridColumnItem;
use TYPO3\CMS\Core\Imaging\Icon;
use TYPO3\CMS\Core\Imaging\IconFactory;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper;

class CollapseViewHelper extends AbstractViewHelper
{
protected $escapeOutput = false;

public function initializeArguments(): void
{
parent::initializeArguments();
$this->registerArgument('contentElementId', 'int', 'Content Element UID', true);
$this->registerArgument('row', 'array', 'Content record array', true);
$this->registerArgument('type', AbstractGridObject::class, '', true);
}

public function render(): string
{
$type = $this->arguments['type'];
$row = $this->arguments['row'];
$contentElementId = $this->arguments['contentElementId'];

$iconFactory = GeneralUtility::makeInstance(IconFactory::class);

if ($type instanceof GridColumnItem && !$type instanceof ContainerGridColumnItem) {
$recordTitle = BackendUtility::getRecordTitle('tt_content', $row);
$typeLabel = $this->getTypeLabel($row);
$isCollapsed = in_array($contentElementId, $this->getCollapsedItems(), true);

return '<button type="button" aria-expanded="' . ($isCollapsed ? 'false' : 'true') . '" data-bs-toggle="collapse" data-bs-target="#element-tt_content-' . $contentElementId . ' > .t3-page-ce-dragitem > .t3-page-ce-body > .element-preview" class="btn btn-default btn-sm" data-b13-collapse="' . $contentElementId . '" data-b13-title="' . GeneralUtility::jsonEncodeForHtmlAttribute(['title' => $recordTitle, 'type' => $typeLabel]) . '">'
. $iconFactory->getIcon('actions-chevron-up', Icon::SIZE_SMALL)->render()
. $iconFactory->getIcon('actions-chevron-down', Icon::SIZE_SMALL)->render()
. '</button>';
}

return '';
}

public function getCollapsedItems(): array
{
$result = $GLOBALS['BE_USER']->uc['B13']['Collapse'] ?? '';
$collapsedItems = GeneralUtility::intExplode(',', $result);

return array_filter($collapsedItems);
}

protected function getTypeLabel(array $row): string
{
$typeValue = BackendUtility::getTCAtypeValue('tt_content', $row);
$label = '';
foreach ($GLOBALS['TCA']['tt_content']['columns']['CType']['config']['items'] as $itm) {
if ($itm['value'] == $typeValue) {
$label = $itm['label'];
break;
}
}
if ($label !== '') {
return $GLOBALS['LANG']->sL($label);
}

return '';
}
}
10 changes: 10 additions & 0 deletions Configuration/JavaScriptModules.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

return [
'dependencies' => ['core', 'backend'],
'imports' => [
'@b13/collapse/' => 'EXT:collapse/Resources/Public/JavaScript/',
],
];
7 changes: 4 additions & 3 deletions Configuration/Services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ services:
public: false
B13\Collapse\:
resource: '../Classes/*'
exclude: '../Classes/Domain/Model/*'

B13\Collapse\PageModuleModifier:
public: true
B13\Collapse\EventListener\ModifyPageLayoutContentEventListener:
tags:
- name: event.listener
identifier: 'paste-reference/backend/modify-page-layout-content'
3 changes: 3 additions & 0 deletions Configuration/page.tsconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
templates.typo3/cms-backend {
1691683586 = b13/collapse:Resources/Private/TemplateOverrides
}
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ This is our bare minimum feature set, a few features will following along:

* Enable / disable collapsing per Content Type
* Disable collapsing in User Settings
* Support for TYPO3 v12
* Customizable preview in collapsed state

## Credits
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<html
xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
xmlns:core="http://typo3.org/ns/TYPO3/CMS/Core/ViewHelpers"
xmlns:c="http://typo3.org/ns/B13/Collapse/ViewHelpers"
data-namespace-typo3-fluid="true"
>

<div class="t3-page-ce-header {f:if(condition: '{allowEditContent} && {item.dragAndDropAllowed}', then: 't3-page-ce-header-draggable t3js-page-ce-draghandle')}">
<div class="t3-page-ce-header-left">
{item.icons -> f:format.raw()}
<f:if condition="{item.siteLanguage.flagIdentifier}">
<span class="t3-page-ce-header-icon-flag t3js-flag" title="{item.siteLanguage.title}">
<core:icon identifier="{item.siteLanguage.flagIdentifier}" />
</span>
</f:if>
</div>
<div class="t3-page-ce-header-title">
{item.contentTypeLabel}
</div>
<div class="t3-page-ce-header-right">
<f:if condition="{item.editable} && {allowEditContent}">
<div class="btn-toolbar">
<div class="btn-group btn-group-sm">
<a href="{item.editUrl}" class="btn btn-default btn-borderless" title="{f:translate(key:'LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:edit')}">
<core:icon identifier="actions-open" />
</a>
<f:if condition="{item.visibilityToggling}">
<a class="btn btn-default btn-borderless" href="{item.visibilityToggleUrl}" title="{item.visibilityToggleTitle}">
<core:icon identifier="actions-edit-{item.visibilityToggleIconName}" />
</a>
</f:if>
<f:if condition="{item.delible}">
<a class="btn btn-default btn-borderless t3js-modal-trigger"
href="{item.deleteUrl}"
data-severity="warning"
data-title="{f:translate(key: 'LLL:EXT:backend/Resources/Private/Language/locallang_alt_doc.xlf:label.confirm.delete_record.title')}"
data-bs-content="{item.deleteMessage}"
data-button-close-text="{f:translate(key: 'LLL:EXT:core/Resources/Private/Language/locallang_common.xlf:cancel')}"
data-button-ok-text="{f:translate(key:'LLL:EXT:core/Resources/Private/Language/locallang_mod_web_list.xlf:delete')}"
title="{f:translate(key: 'LLL:EXT:backend/Resources/Private/Language/locallang_layout.xlf:deleteItem')}">
<core:icon identifier="actions-edit-delete" size="small" />
</a>
</f:if>
<button aria-haspopup="true"
aria-controls="contentMenu0" aria-label="{f:translate(key: 'LLL:EXT:backend/Resources/Private/Language/locallang_layout.xlf:advancedFunctions')}"
class="btn btn-default btn-borderless btn-sm"
data-contextmenu-trigger="click"
data-contextmenu-table="tt_content"
data-contextmenu-uid="{item.record.uid}">
<core:icon identifier="actions-menu-alternative" />
</button>
</div>
<c:collapse contentElementId="{item.record.uid}" row="{item.record}" type="{item}" />
</div>
</f:if>
</div>
</div>
6 changes: 3 additions & 3 deletions Resources/Public/Css/pagemodule.css
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
.t3-page-ce-header-icons-left button[data-b13-collapse] {
.t3-page-ce-header-left button[data-b13-collapse] {
display: none;
}

.t3-page-ce-header-icons-right button[data-b13-collapse][aria-expanded=false] > span:first-child {
.t3-page-ce-header-right button[data-b13-collapse][aria-expanded=false] > span:first-child {
display: none;
}
.t3-page-ce-header-icons-right button[data-b13-collapse][aria-expanded=true] > span:last-child {
.t3-page-ce-header-right button[data-b13-collapse][aria-expanded=true] > span:last-child {
display: none;
}
32 changes: 15 additions & 17 deletions Resources/Public/JavaScript/PageModuleCollapse.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
/**
* Detects content elements to enable expand/collapse
*/
define([
'TYPO3/CMS/Core/DocumentService',
'TYPO3/CMS/Backend/Storage/Persistent',
], function (DocumentService, PersistentStorage) {
let selectors = {
button: 'button[data-b13-collapse]',
toolbarContainer: '.t3-page-ce-header',
rightToolbarContainer: '.t3-page-ce-header-icons-right > .btn-toolbar'
};
import Persistent from '@typo3/backend/storage/persistent.js';
import DocumentService from '@typo3/core/document-service.js';

DocumentService.ready().then(() => {
let selectors = {
button: 'button[data-b13-collapse]',
toolbarContainer: '.t3-page-ce-header',
rightToolbarContainer: '.t3-page-ce-header-right > .btn-toolbar'
};
document.querySelectorAll(selectors.button).forEach((btn) => {
const substituteContent = JSON.parse(btn.dataset.b13Title);
// move each element to the right spot first.
let toolbar = btn.closest(selectors.toolbarContainer);
btn.remove();
if (document.querySelector(btn.dataset.bsTarget) == null) {
// no element-preview
return;
}
toolbar.querySelector(selectors.rightToolbarContainer).append(btn);
const substituteNode = document.createElement('div');
substituteNode.innerHTML = '<strong>' + substituteContent['title'] + '</strong>' + ' ' + substituteContent['type'];
Expand All @@ -31,20 +30,19 @@ define([
// Add event handles to update BE_USERs->uc when collapse/show is used
// The CE is expanded again
document.querySelector(btn.dataset.bsTarget).addEventListener('show.bs.collapse', () => {
PersistentStorage.removeFromList('B13.Collapse', btn.dataset.b13Collapse);
Persistent.removeFromList('B13.Collapse', btn.dataset.b13Collapse);
substituteNode.classList.add('d-none');
});
// The CE is about to be collapsed
document.querySelector(btn.dataset.bsTarget).addEventListener('hide.bs.collapse', () => {
if (PersistentStorage.isset('B13.Collapse') === false) {
PersistentStorage.set('B13.Collapse','');
if (Persistent.isset('B13.Collapse') === false) {
Persistent.set('B13.Collapse','');
}
PersistentStorage.addToList('B13.Collapse', btn.dataset.b13Collapse);
Persistent.addToList('B13.Collapse', btn.dataset.b13Collapse);
substituteNode.classList.remove('d-none');
});

// Add the substitute content
document.querySelector(btn.dataset.bsTarget).parentNode.prepend(substituteNode);
});
});
});
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"GPL-2.0-or-later"
],
"require": {
"typo3/cms-backend": "^11.5"
"typo3/cms-backend": "^12.4 || ^13.4"
},
"autoload": {
"psr-4": {
Expand Down
6 changes: 4 additions & 2 deletions ext_emconf.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<?php

declare(strict_types=1);

$EM_CONF[$_EXTKEY] = [
'title' => 'Content Element Collapse or Expand View in TYPO3 Page Module',
'description' => 'Collapse large content element previews in TYPO3\'s Page Module.',
Expand All @@ -8,10 +10,10 @@
'author' => 'b13 GmbH',
'author_email' => 'typo3@b13.com',
'author_company' => '',
'version' => '1.0.0',
'version' => '2.0.0',
'constraints' => [
'depends' => [
'typo3' => '11.5.0-11.5.99',
'typo3' => '12.4.0-13.99.99',
],
'conflicts' => [],
'suggests' => [],
Expand Down
8 changes: 6 additions & 2 deletions ext_localconf.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
<?php

declare(strict_types=1);

defined('TYPO3') or die('Access denied.');

$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/db_layout.php']['drawHeaderHook']['collapse'] = \B13\Collapse\PageModuleModifier::class . '->addJavaScript';
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['recStatInfoHooks']['collapse'] = \B13\Collapse\PageModuleModifier::class . '->addCollapseButton';
if (!is_array($GLOBALS['TYPO3_CONF_VARS']['BE']['stylesheets'] ?? null)) {
$GLOBALS['TYPO3_CONF_VARS']['BE']['stylesheets'] = [];
}
$GLOBALS['TYPO3_CONF_VARS']['BE']['stylesheets']['b13/collapse'] = 'EXT:collapse/Resources/Public/Css/';
5 changes: 0 additions & 5 deletions ext_tables.php

This file was deleted.