TYPO3 tx_mask: FlexForm in Mask nutzen

Die beste Extension für TYPO3? Ganz klar: mask. Ohne Mask wollen wir nicht mehr. Ohne Mask macht TYPO3 keinen Sinn.

Nur eine ganz kleine Sache fehlt uns immer wieder bei Projekten, bei denen wir Mask einsetzen: Die Möglichkeit, FlexForms innerhalb von Mask zu nutzen. Ja, wir wissen: Mask hat sich bewusst GEGEN das Konzept der FlexForms entschieden – und diese Entscheidung ist absolut nachvollziehbar und berechtigt. Mask verfolgt das Konzept, jedes Feld aus zusätzliche Spalte in der Datenbank-Tabelle „tt_content“ anzulegen. Allerdings gibt es Anwendungsfälle, in denen einem das als „zu viel“. Beispiele dafür könnten sein:

  • Man möchte mit EXT:mask einen Slider bauen, den man im Backend umfangreich und responsive konfigurieren kann. Der Redakteur soll z.B. für jede Bildschirmgröße die Zahl der Slides nebeneinander oder die Größen definieren können.
  • Der Redakteur soll für ein Inhaltselement ein umfangreiches Styling definieren können, z.B. Hintergrundfarben, Schriftgrößen etc.

Bei solchen Fällen enstehen ohne FlexForms schnell mal 10+ zusätzliche Felder in der Tabelle tt_content. Grundsätzlich nicht „schlimm“ – aber beim Einsatz von vielen Mask-Elementen wächst die Tabelle schnell in die Breite und man verliert die Übersicht über die Felder. Oder es gehen einem (wie mir manchmal) die Ideen für Feldnamen aus.

FlexForms in EXT:mask für TYPO3 nutzen

Mit einem einfachen Trick lassen sich Felder, die in dem Backend-Modul von Mask angelegt wurden nachträglich als FlexForm definieren. Die Vorgehensweise ist simpel:

  1. Über das schönen GUI von Mask im Backend legt man für ein Mask-Element ein „normales“ mehrzeiliges Textfeld an. In diesem Beispiel geben wir als Feld-Key design an.
  2. Nach dem Speichern des Mask-Elementes wird die Tabelle tt_content jetzt automatisch um die Spalte tx_mask_design erweitert. Das Präfix tx_mask_ wird automatisch immer vor das Feld-Key gehängt, um Konflikte zu vermeiden.
  3. In seiner Template/Site-Extension definiert man jetzt in der ext_emconf.php und composer.json ein dependency zu mask. Das ist wichtig, damit die eigene Extension immer nach EXT:mask geladen wird.
  4. Ich empfehle, die Template-Extension im Extensionmanager kurz zu deaktivieren und neu zu aktivieren, damit die Ladereihenfolge der Extensions korrekt neu berechnet wird.
  5. In die ext_tables.php wird jetzt das Feld der Tabelle tt_content manuell überschrieben:
    // only override TCA if we are NOT in the Mask Backend Module / GUI
    if ($_GET['route'] != '/module/tools/MaskMask') {
       $GLOBALS['TCA']['tt_content']['columns']['tx_mask_design']['config'] = [
          'type' => 'flex',
          'ds' => [
             'default' => 'FILE:EXT:myext/Configuration/FlexForm/tx_mask_design.xml',
          ],
       ];
    }

    Falls die Extension nnhelpers genutzt wird, lässt sich der Code weiter reduzieren und für zukünftige Versionen von TYPO3 stabilisieren:

    if ($_GET['route'] != '/module/tools/MaskMask') {
       if ($GLOBALS['TCA']['tt_content']['columns']['tx_mask_design']) {
          $GLOBALS['TCA']['tt_content']['columns']['tx_mask_design']['config'] = 
             \nn\t3::TCA()->insertFlexForm('FILE:EXT:myext/Configuration/FlexForm/tx_mask_design.xml');
       }
    }
  6. Das Flexform in EXT:myext/Configuration/FlexForm/tx_mask_design.xml kann z.B. so aussehen:
    <T3DataStructure>
       <meta>
          <langDisable>1</langDisable>
       </meta>
       <sheets>
          <sDEF>
             <ROOT>
                <TCEforms>
                   <sheetTitle>Einstellungen</sheetTitle>
                </TCEforms>
                <type>array</type>
                <el>
                   <themeColor>
                      <TCEforms>
                         <label>Theme-Color</label>
                         <config>
                            <type>input</type>
                            <renderType>colorpicker</renderType>
                            <size>10</size>
                         </config>
                      </TCEforms>
                   </themeColor>
                   <colorPrimary>
                      <TCEforms>
                         <label>Primärfarbe (hell)</label>
                         <config>
                            <type>input</type>
                            <renderType>colorpicker</renderType>
                            <size>10</size>
                         </config>
                      </TCEforms>
                   </colorPrimary>
                </el>
             </ROOT>
          </sDEF>
       </sheets>
    </T3DataStructure>

FlexForm in PHP parsen

Um das FlexForm später in der eigenen Extension oder einem ViewHelper zu parsen, lohnt sich ein Blick in die Extension nnhelpers – dort findet man Beispiele, wie sich das FlexForm unkompliziert im Mask-Template auslesen und parsen lässt:

https://docs.typo3.org/p/nng/nnhelpers/main/en-us/Helpers/Classes/flexform.html

// Innerhalb der Extension:
\nn\t3::Flexform()->parse( $data['tx_mask_design'] );

// ...oder direkt im Fluid-Template
{data.tx_mask_design->nnt3:parse.flexForm()->f:debug()}

Randnotiz: Warum ext_tables.php und nicht ein Override der tt_content.php?

Jeder, der die Felder in tt_content überschreibt oder modifiziert wird als erstes denken: Müsste das Script zum Überschreiben des TCA nicht eigentlich an dieser Stelle stehen: EXT:myext/Configuration/TCA/Overrides/tt_content.php?

Ja – ABER: Nachdem das TCA gerendert wird, landet es im TYPO3 Cache – und das gibt in diesem Fall Probleme. Da das mask Backend-Modul versucht, das „FlexForm“-Element zu rendern, wirft das Backend einen Fehler. Um das zu vermeiden, haben wir im Script oben einen IF-Befehl: $_GET['route'] != '/module/tools/MaskMask'. Leider wird das IF aber nach dem Cachen nicht mehr beachtet – deshalb verlagern wir das Script in die nicht-gecachte ext_tables.php.