FlexformDataProcessor für Custom Content Elements

Um individuelle Inhaltselemente zu erstellen, nutze ich bereits seit Jahren gerne Mask (zum Teil mit mask_export) und gridelements. So toll mask auch ist, es hat seine Grenzen und dann erstelle ich auch mal komplett eigene Inhaltselemente – „from scratch“ sozusagen. Eine gute Anleitung hierfür gibt es bei TYPO3 Explained.

Wenn es um irgendwelche kleinen Einstellungen geht (Farbe, Ausrichtung etc.), dann finde ich es manchmal etwas übertrieben, dafür direkt ein Datenbankfeld zu generieren, vor allem, wenn man diese Einstellungen nur in einem Inhaltselement braucht. Was ich auch niemals mache, ist andere Felder zu zweckentfremden. Spätestens dann, wenn das Originalfeld benötigt wird, hat man ein Problem.

Genau für solchen Zweck gibt es bei TYPO3 die Flexforms. Sie können genauso konfiguriert werden wie TCA, ermöglichen das anlegen von Feldern in Tabs und sind insgesamt sehr flexibel (pun intended). In der Ausgabe hat man dann allerdings das Problem, dass alle Flexform-Werte in einem XML-Konstrukt stehen. Zum Glück hat TYPO3 die Data Prozessoren. Meine Recherche (vor ein paar Monaten) hat keinen fertigen FlexformDataProcessor zutage gebracht, so dass ich kurzerhand meinen eigenen geschrieben habe.

<?php
namespace Vendor\MyExtension\DataProcessing;
 
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface;
 
class FlexformDataProcessor implements DataProcessorInterface
{
    public function process(ContentObjectRenderer $cObj, array $contentObjectConfiguration, array $processorConfiguration, array $processedData)
    {
        if (empty($processedData['data']['pi_flexform'])) {
            return $processedData;
        }
 
        $flexformData = GeneralUtility::xml2array($processedData['data']['pi_flexform']);
        $flexformProcessed = [];
        foreach ($flexformData['data'] as $sheetKey => $sheetValue) {
            foreach ($sheetValue['lDEF'] as $fieldKey => $fieldValue) {
                $key = $sheetKey . '_' . $fieldKey;
                $flexformProcessed[$key] = $fieldValue['vDEF'];
            }
        }
 
        $targetVariableName = $cObj->stdWrapValue('as', $processorConfiguration, 'flexform_data');
        $processedData[$targetVariableName] = $flexformProcessed;
 
        return $processedData;
    }
}

Und so kann man den Flexform Data Processor dann einsetzen:

tt_content.mycontentelement = FLUIDTEMPLATE
tt_content.mycontentelement {
    dataProcessing.10 = Vendor\MyExtension\DataProcessing\FlexformDataProcessor
    dataProcessing.10 {
        as = flexform_data
    }
}

Auf das Ergebnis kann man dann im Template mit {flexform_data} zugreifen.

5 Kommentare

  1. Julian

    Es ist kein ViewHelper, aber \TYPO3\CMS\Backend\View\PageLayoutView::renderContentElementPreviewFromFluidTemplate() bereitet pi_flexform auch für die Nutzung in Fluid vor. Vielleicht lohnt sich auch ein Blick dorthin.

  2. Christopher

    Danke für den Beitrag 🙂 Ich habe heute die flex section container getestet.

    Leider bekomme ich die Daten so geliefert:

    emails => array(2 items)
    5eed21aab6294871086793 => array(1 item)
    container => array(1 item)
    email => ‚www.deadfsdasasssdfds‘ (21 chars)
    5eed21b04dbeb100785974 => array(1 item)
    container => array(1 item)
    email => ‚www2.defasdasdsssdasdsdf‘ (24 chars)

    Statt der zufälligen Zahlenfolge wäre die Ausgabe so besser:

    emails => array(2 items)
    1 => array(1 item)
    container => array(1 item)
    email => ‚www.deadfsdasasssdfds‘ (21 chars)
    2 => array(1 item)
    container => array(1 item)
    email => ‚www2.defasdasdsssdasdsdf‘ (24 chars)

    Leider konnte ich keine Lösung dafür finden. Für Tipps wäre ich dankbar 🙂

  3. Perseida Theodora

    Kann man damit auch Daten im Flexform ändern und speichern? Angenommen man erzeugt automatisch ein neues tt_content element, das eine Flexform enthalten soll – bekommt man den nötigen xml-string mittels des DataProzessors?