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

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

Mit Hilfe der Felder tt_content.layout und tt_content.frame_class kann man das Aussehen von Inhaltselementen und Plugins im Frontend beeinflussen. Aber vielleicht soll sich die Liste der Optionen im Backend von TYPO3 an zuvor gemachte Einstellungen anpassen? Schließlich wollen wir die Redakteure nicht auch noch mit nicht-funktionierenden Optionen belasten. Falls ihr so etwas sucht, haben wir vielleicht genau das Richtige für euch.

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.

TYPO3: Unbenutzte Dateien im fileadmin finden

Ihr wollt unbenutzte oder verwaiste Dateien im fileadmin oder einer anderen Storage löschen? Leider gibt es hier nichts direkt vom Core. Aber ein kleiner Command in eurem Sitepackage hilft schnell...

Zum Beitrag

TYPO3: Redakteure mit individuellen user_upload Folder

Vielleicht kennt ihr die Kundenanforderung? Redakteure sollen Videos über den Button "Add media by URL" hinzufügen können. Aber die Dateien sollen sich dann nicht in fileadmin/user_upload/ sondern in...

Zum Beitrag

TYPO3: Seiten im Mixed Mode finden

Mixed Mode bezeichnet man in TYPO3 übersetzte Seiten, auf denen sich Seiteninhalte befinden, die nur zum Teil eine Relation auf entsprechende Seiteninhalte in der Hauptsprache haben. Dies wird im...

Zum Beitrag

Extbase Extensions: An Erweiterbarkeit denken mit data, site und language

Heute mal eine kleine Bitte an die TYPO3-Extension-Autoren da draußen: Achtet auf Erweiterbarkeit eurer Extensions. Dies fördert dann auch die Verbreitung der entsprechenden Plugins.

Zum Beitrag

SQL: Zeige alle Tabellen absteigend nach Größe sortiert

Ich brauche in letzter Zeit häufiger den SQL-Befehl, um herauszufinden, welche Tabellen in der TYPO3-Datenbank am größten sind. Ich habe das Snippet einmal veröffentlicht.

Zum Beitrag

TYPO3 12 mit CKEditor 5: Stile als Einfachauswahl

Wenn man im RTE in TYPO3 einen Link setzt, kann es sein, dass man zwischen verschiedenen Link-Klassen auswählen muss, um beispielsweise Buttons im Frontend zu erzeugen. Neu ist in TYPO3 12 dass man...

Zum Beitrag