Skip to content

Commit

Permalink
[WIP] backend template
Browse files Browse the repository at this point in the history
  • Loading branch information
achimfritz committed Jan 22, 2025
1 parent 9d29e35 commit 749ccf7
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 109 deletions.
112 changes: 6 additions & 106 deletions Classes/Backend/Preview/ContainerPreviewRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,122 +12,22 @@
* of the License, or any later version.
*/

use B13\Container\Backend\Grid\ContainerGridColumn;
use B13\Container\Backend\Grid\ContainerGridColumnItem;
use B13\Container\Backend\Service\NewContentUrlBuilder;
use B13\Container\Domain\Factory\Exception;
use B13\Container\Domain\Factory\PageView\Backend\ContainerFactory;
use B13\Container\Events\BeforeContainerPreviewIsRenderedEvent;
use B13\Container\Tca\Registry;
use Psr\EventDispatcher\EventDispatcherInterface;

use TYPO3\CMS\Backend\Preview\StandardContentPreviewRenderer;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Backend\View\BackendLayout\Grid\Grid;
use TYPO3\CMS\Backend\View\BackendLayout\Grid\GridColumnItem;
use TYPO3\CMS\Backend\View\BackendLayout\Grid\GridRow;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Fluid\View\StandaloneView;

class ContainerPreviewRenderer extends StandardContentPreviewRenderer
{
/**
* @var Registry
*/
protected $tcaRegistry;

/**
* @var ContainerFactory
*/
protected $containerFactory;

protected NewContentUrlBuilder $newContentUrlBuilder;
protected GridRenderer $gridRenderer;

/**
* @var EventDispatcherInterface
*/
protected $eventDispatcher;

public function __construct(
Registry $tcaRegistry,
ContainerFactory $containerFactory,
NewContentUrlBuilder $newContentUrlBuilder,
EventDispatcherInterface $eventDispatcher
) {
$this->eventDispatcher = $eventDispatcher;
$this->tcaRegistry = $tcaRegistry;
$this->containerFactory = $containerFactory;
$this->newContentUrlBuilder = $newContentUrlBuilder;
public function __construct(GridRenderer $gridRenderer) {
$this->gridRenderer = $gridRenderer;
}

public function renderPageModulePreviewContent(GridColumnItem $item): string
{
$content = parent::renderPageModulePreviewContent($item);
$context = $item->getContext();
$record = $item->getRecord();
$grid = GeneralUtility::makeInstance(Grid::class, $context);
try {
$container = $this->containerFactory->buildContainer((int)$record['uid']);
} catch (Exception $e) {
// not a container
return $content;
}
$containerGrid = $this->tcaRegistry->getGrid($record['CType']);
foreach ($containerGrid as $cols) {
$rowObject = GeneralUtility::makeInstance(GridRow::class, $context);
foreach ($cols as $col) {
$defVals = $this->getDefValsForContentDefenderAllowsOnlyOneSpecificContentType($record['CType'], (int)$col['colPos']);
$url = $this->newContentUrlBuilder->getNewContentUrlAtTopOfColumn($context, $container, (int)$col['colPos'], $defVals);
$columnObject = GeneralUtility::makeInstance(ContainerGridColumn::class, $context, $col, $container, $url, $defVals !== null);
$rowObject->addColumn($columnObject);
if (isset($col['colPos'])) {
$records = $container->getChildrenByColPos($col['colPos']);
foreach ($records as $contentRecord) {
$url = $this->newContentUrlBuilder->getNewContentUrlAfterChild($context, $container, (int)$col['colPos'], (int)$contentRecord['uid'], $defVals);
$columnItem = GeneralUtility::makeInstance(ContainerGridColumnItem::class, $context, $columnObject, $contentRecord, $container, $url);
$columnObject->addItem($columnItem);
}
}
}
$grid->addRow($rowObject);
}

$gridTemplate = $this->tcaRegistry->getGridTemplate($record['CType']);
$partialRootPaths = $this->tcaRegistry->getGridPartialPaths($record['CType']);
$layoutRootPaths = $this->tcaRegistry->getGridLayoutPaths($record['CType']);
$view = GeneralUtility::makeInstance(StandaloneView::class);
$view->setPartialRootPaths($partialRootPaths);
$view->setLayoutRootPaths($layoutRootPaths);
$view->setTemplatePathAndFilename($gridTemplate);

$view->assign('hideRestrictedColumns', (bool)(BackendUtility::getPagesTSconfig($context->getPageId())['mod.']['web_layout.']['hideRestrictedCols'] ?? false));
$view->assign('newContentTitle', $this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_layout.xlf:newContentElement'));
$view->assign('newContentTitleShort', $this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_layout.xlf:content'));
$view->assign('allowEditContent', $this->getBackendUser()->check('tables_modify', 'tt_content'));
// keep compatibility
$view->assign('containerGrid', $grid);
$view->assign('grid', $grid);
$view->assign('containerRecord', $record);
$view->assign('context', $context);
$beforeContainerPreviewIsRendered = new BeforeContainerPreviewIsRenderedEvent($container, $view, $grid, $item);
$this->eventDispatcher->dispatch($beforeContainerPreviewIsRendered);
$rendered = $view->render();

return $content . $rendered;
}

protected function getDefValsForContentDefenderAllowsOnlyOneSpecificContentType(string $cType, int $colPos): ?array
{
$contentDefefenderConfiguration = $this->tcaRegistry->getContentDefenderConfiguration($cType, $colPos);
$allowedCTypes = GeneralUtility::trimExplode(',', $contentDefefenderConfiguration['allowed.']['CType'] ?? '', true);
$allowedListTypes = GeneralUtility::trimExplode(',', $contentDefefenderConfiguration['allowed.']['list_type'] ?? '', true);
if (count($allowedCTypes) === 1) {
if ($allowedCTypes[0] !== 'list') {
return ['CType' => $allowedCTypes[0]];
}
if (count($allowedListTypes) === 1) {
return ['CType' => 'list', 'list_type' => $allowedListTypes[0]];
}
}
return null;
$grid = $this->gridRenderer->renderGrid($item->getRecord(), $item->getContext(), $item);
return $content . $grid;
}
}
130 changes: 130 additions & 0 deletions Classes/Backend/Preview/GridRenderer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
<?php

declare(strict_types=1);

namespace B13\Container\Backend\Preview;

/*
* This file is part of TYPO3 CMS-based extension "container" by b13.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*/

use B13\Container\Backend\Grid\ContainerGridColumn;
use B13\Container\Backend\Grid\ContainerGridColumnItem;
use B13\Container\Backend\Service\NewContentUrlBuilder;
use B13\Container\Domain\Factory\Exception;
use B13\Container\Domain\Factory\PageView\Backend\ContainerFactory;
use B13\Container\Events\BeforeContainerPreviewIsRenderedEvent;
use B13\Container\Tca\Registry;
use Psr\EventDispatcher\EventDispatcherInterface;
use TYPO3\CMS\Backend\Utility\BackendUtility;
use TYPO3\CMS\Backend\View\BackendLayout\Grid\Grid;
use TYPO3\CMS\Backend\View\BackendLayout\Grid\GridColumnItem;
use TYPO3\CMS\Backend\View\BackendLayout\Grid\GridRow;
use TYPO3\CMS\Backend\View\PageLayoutContext;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
use TYPO3\CMS\Core\Localization\LanguageService;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Fluid\View\StandaloneView;

class GridRenderer
{

protected Registry $tcaRegistry;
protected ContainerFactory $containerFactory;
protected NewContentUrlBuilder $newContentUrlBuilder;
protected EventDispatcherInterface $eventDispatcher;

public function __construct(
Registry $tcaRegistry,
ContainerFactory $containerFactory,
NewContentUrlBuilder $newContentUrlBuilder,
EventDispatcherInterface $eventDispatcher
) {
$this->eventDispatcher = $eventDispatcher;
$this->tcaRegistry = $tcaRegistry;
$this->containerFactory = $containerFactory;
$this->newContentUrlBuilder = $newContentUrlBuilder;
}

public function renderGrid(array $record, PageLayoutContext $context, ?GridColumnItem $parentGridColumnItem = null): string
{
$grid = GeneralUtility::makeInstance(Grid::class, $context);
try {
$container = $this->containerFactory->buildContainer((int)$record['uid']);
} catch (Exception $e) {
// not a container
return '';
}
$containerGrid = $this->tcaRegistry->getGrid($record['CType']);
foreach ($containerGrid as $cols) {
$rowObject = GeneralUtility::makeInstance(GridRow::class, $context);
foreach ($cols as $col) {
$defVals = $this->getDefValsForContentDefenderAllowsOnlyOneSpecificContentType($record['CType'], (int)$col['colPos']);
$url = $this->newContentUrlBuilder->getNewContentUrlAtTopOfColumn($context, $container, (int)$col['colPos'], $defVals);
$columnObject = GeneralUtility::makeInstance(ContainerGridColumn::class, $context, $col, $container, $url, $defVals !== null);
$rowObject->addColumn($columnObject);
if (isset($col['colPos'])) {
$records = $container->getChildrenByColPos($col['colPos']);
foreach ($records as $contentRecord) {
$url = $this->newContentUrlBuilder->getNewContentUrlAfterChild($context, $container, (int)$col['colPos'], (int)$contentRecord['uid'], $defVals);
$columnItem = GeneralUtility::makeInstance(ContainerGridColumnItem::class, $context, $columnObject, $contentRecord, $container, $url);
$columnObject->addItem($columnItem);
}
}
}
$grid->addRow($rowObject);
}

$gridTemplate = $this->tcaRegistry->getGridTemplate($record['CType']);
$partialRootPaths = $this->tcaRegistry->getGridPartialPaths($record['CType']);
$layoutRootPaths = $this->tcaRegistry->getGridLayoutPaths($record['CType']);
$view = GeneralUtility::makeInstance(StandaloneView::class);
$view->setPartialRootPaths($partialRootPaths);
$view->setLayoutRootPaths($layoutRootPaths);
$view->setTemplatePathAndFilename($gridTemplate);

$view->assign('hideRestrictedColumns', (bool)(BackendUtility::getPagesTSconfig($context->getPageId())['mod.']['web_layout.']['hideRestrictedCols'] ?? false));
$view->assign('newContentTitle', $this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_layout.xlf:newContentElement'));
$view->assign('newContentTitleShort', $this->getLanguageService()->sL('LLL:EXT:backend/Resources/Private/Language/locallang_layout.xlf:content'));
$view->assign('allowEditContent', $this->getBackendUser()->check('tables_modify', 'tt_content'));
// keep compatibility
$view->assign('containerGrid', $grid);
$view->assign('grid', $grid);
$view->assign('containerRecord', $record);
$view->assign('context', $context);
$beforeContainerPreviewIsRendered = new BeforeContainerPreviewIsRenderedEvent($container, $view, $grid, $parentGridColumnItem);
$this->eventDispatcher->dispatch($beforeContainerPreviewIsRendered);
$rendered = $view->render();
return $rendered;
}

protected function getDefValsForContentDefenderAllowsOnlyOneSpecificContentType(string $cType, int $colPos): ?array
{
$contentDefefenderConfiguration = $this->tcaRegistry->getContentDefenderConfiguration($cType, $colPos);
$allowedCTypes = GeneralUtility::trimExplode(',', $contentDefefenderConfiguration['allowed.']['CType'] ?? '', true);
$allowedListTypes = GeneralUtility::trimExplode(',', $contentDefefenderConfiguration['allowed.']['list_type'] ?? '', true);
if (count($allowedCTypes) === 1) {
if ($allowedCTypes[0] !== 'list') {
return ['CType' => $allowedCTypes[0]];
}
if (count($allowedListTypes) === 1) {
return ['CType' => 'list', 'list_type' => $allowedListTypes[0]];
}
}
return null;
}

protected function getBackendUser(): BackendUserAuthentication
{
return $GLOBALS['BE_USER'];
}

protected function getLanguageService(): LanguageService
{
return $GLOBALS['LANG'];
}
}
6 changes: 3 additions & 3 deletions Classes/Events/BeforeContainerPreviewIsRenderedEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ final class BeforeContainerPreviewIsRenderedEvent

protected Grid $grid;

protected GridColumnItem $item;
protected ?GridColumnItem $item;

public function __construct(Container $container, StandaloneView $view, Grid $grid, GridColumnItem $item)
public function __construct(Container $container, StandaloneView $view, Grid $grid, ?GridColumnItem $item)
{
$this->container = $container;
$this->view = $view;
Expand All @@ -50,7 +50,7 @@ public function getGrid(): Grid
return $this->grid;
}

public function getItem(): GridColumnItem
public function getItem(): ?GridColumnItem
{
return $this->item;
}
Expand Down

0 comments on commit 749ccf7

Please sign in to comment.