For coders TYPO3 Tech Corner

[TYPO3] tt_content.layout und .frame_class Optionen dynamisch setzen

[TYPO3] tt_content.layout und .frame_class Optionen dynamisch setzen

Wie ihr die Optionen einfach per Page TSconfig verändern könnt - auch je nach CType, ist gut in der TYPO3 Dokumentation beschrieben - z.B.:
 

TCEFORM { tt_content { layout { removeItems = 0,1,2,3 types { # Change labels for CType textpic textpic { addItems { 10 = Red 20 = Blue } } # Change labels for CType textmedia textmedia { removeItems = 1,2 altLabels { 0 = Standard 1 = Pink } } } } } }

Tipp: Statt die Labels hardcoded einzutragen, könnt ihr auch die LLL-Syntax in TYPO3 nutzen, um euren Redakteuren lokalisierte Optionen anzubieten.

ItemsProcFunc

Wenn dies (mit oder ohne Conditions) aber einmal nicht mehr ausreicht, und ihr wollt abhängig von mehreren Faktoren beeinflussen, welche Optionen angezeigt werden, könnt ihr itemsProcFunc zur Hilfe holen. Dazu müsst ihr in eurem Sitepackage in der Datei Configuration/TCA/Overrides/tt_content.php eine oder mehrere itemsProcFunc aufrufen, um die Auswahlliste beliebig einzuschränken. In diesem Beispiel eben für die Felder layout und frame_class:

$GLOBALS['TCA']['tt_content']['columns']['layout']['config']['itemsProcFunc'] = \Vendor\Sitepackage\Tca\TtContentLayoutOptions::class . '->addOptions'; $GLOBALS['TCA']['tt_content']['columns']['frame_class']['config']['itemsProcFunc'] = \Vendor\Sitepackage\Tca\TtContentLayoutOptions::class . '->addOptions';

Die UserFunc hierzu kann dann beispielsweise so aussehen:

<?php declare(strict_types=1); namespace Vendor\Sitepackage\Tca; use Vendor\Sitepackage\Utility\BackendUtility; /** * Class TtContentLayoutOptions * to show field options of tt_content.layout and .frame_class when some conditions are fitting */ class TtContentLayoutOptions { /** * @var array */ protected $mapping = [ 'layout' => [ [ 'conditions' => [ 'fields' => [ 'CType' => [ 'textpic' ] ] ], 'options' => [ [ 'weiß', '0' ], [ 'Box mit Bild', 'box-picture', ], ], ], [ 'conditions' => [ 'fields' => [ 'CType' => [ 'gridelements_pi1' ], 'tx_gridelements_backend_layout' => [ 'one-column' ] ] ], 'options' => [ [ 'Weiß', '10' ], [ 'Grau', '20', ], ], ], [ 'conditions' => [ 'fields' => [ 'CType' => [ 'list' ], 'list_type' => [ 'news_pi1' ] ] ], 'options' => [ [ 'Einzelansicht', '1000' ], [ 'Liste - 100%', '100', ], ], ] ], 'frame_class' => [ [ 'conditions' => [ 'fields' => [ 'CType' => [ 'div' ] ] ], 'options' => [ [ 'Standard', '0' ], [ 'Trenner Grau', 'divider-grey', ], ], ], [ 'conditions' => [ 'fields' => [ 'CType' => [ 'textpic' ], 'layout' => [ 'box-picture' ] ] ], 'options' => [ [ 'Graue Box mit Bild oben', 'grey-box-imagetop', ], [ 'Graue Box mit Bild unten', 'grey-box-imagebottom', ], ], ], [ 'conditions' => [ 'fields' => [ 'CType' => [ 'textpic' ], 'layout' => [ 'colorvariants' ] ] ], 'options' => [ [ 'Grauer Hintergrund', 'components', ], [ 'Roter Hintergrund', 'primary-1', ], ], ], [ 'conditions' => [ 'fields' => [ 'CType' => [ 'textpic' ], 'layout' => [ 'colorvariants' ] ], 'functions' => [ 'isSuperEditorOrAdminCondition' ] ], 'options' => [ [ 'Hellblauer Hintergrund', 'info' ], [ 'Hellblauer Rahmen', 'outline-info' ] ] ], [ 'conditions' => [ 'fields' => [ 'CType' => [ 'textpic' ], 'layout' => [ 'box-overlay' ] ], ], 'options' => [ [ 'LLL:EXT:sitepackage/Resources/Private/Language/Backend/locallang.xlf:' . 'tt_content.frame_class.box-overlay-bright', 'box-overlay-bright' ], [ 'LLL:EXT:sitepackage/Resources/Private/Language/Backend/locallang.xlf:' . 'tt_content.frame_class.box-overlay-dark', 'box-overlay-dark' ], ] ], [ 'conditions' => [ 'fields' => [ 'CType' => [ 'list' ], 'list_type' => [ 'news_pi1' ], 'layout' => [ '66', '444', '100' ] ], ], 'options' => [ [ 'Standard', '1' ], [ 'Standard mit Bild', '14' ], ] ], ] ]; /** * Values of tt_content.* * * @var array */ protected $properties = []; /** * Options like * [ * [ * 'label 1', * 'value 1' * ], * [ * 'label 2', * 'value 2' * ] * ] * * @var array */ protected $items = []; /** * Current field where userFunc was added (e.g. "layout" or "frame_class") * * @var string */ protected $field = ''; /** * @param array $params * @return void */ protected function initialize(array &$params): void { $this->properties = $params['row']; if (is_array($this->properties['CType'])) { $this->properties['CType'] = $this->properties['CType'][0]; } if (is_array($this->properties['layout'])) { $this->properties['layout'] = $this->properties['layout'][0]; } if (is_array($this->properties['frame_class'])) { $this->properties['frame_class'] = $this->properties['frame_class'][0]; } $this->items = &$params['items']; $this->items = []; $this->field = $params['field']; } /** * @param array $params * @return void */ public function addOptions(array &$params): void { $this->initialize($params); $this->setOptions(); } /** * @return void */ protected function setOptions(): void { foreach ($this->mapping[$this->field] as $configuration) { if ($this->isConditionMatching($configuration['conditions'])) { $this->items = array_merge($this->items, $configuration['options']); } } } /** * @param array $conditions * @return bool */ protected function isConditionMatching(array $conditions): bool { if (isset($conditions['fields'])) { foreach ($conditions['fields'] as $startField => $compareFields) { if (in_array($this->properties[$startField], $compareFields) === false) { return false; } } } if (isset($conditions['functions'])) { foreach ($conditions['functions'] as $function) { if ($this->{$function}() === false) { return false; } } } return true; } /** * @return bool * @noinspection PhpUnused */ protected function isSuperEditorOrAdminCondition(): bool { return BackendUtility::isAdministrator() || BackendUtility::isSuperEditor(); } }

Über die Eigenschaft mapping wird definiert welche Optionen pro Feld ausgegeben werden sollen. Mit Hilfe des Keys conditions kann man definieren, wann diese Optionen ausgespielt werden sollen.

Hinweis: Die Funktionen isAdministrator() und isSuperEditor() haben wir hier nicht mehr beigefügt. Dies lässt sich aber mit dem Zugriff auf $GLOBALS['BE_USER'] ganz schnell selber umsetzen.

Zurück

Kennst du das: Immer nur schnell schnell?

Wie wäre es einmal mit Zeit und Respekt für Codequalität? Arbeiten im Team? Automatisierte Tests?

Komm zu uns