Ich möchte hier gerne eine Frage von @Thomas Hilburger aus Discord nochmal aufgreifen, um meine Lösung auch hier im Forum zu teilen.
Frage:
Moin allerseits!
Ich bin ja aktuell dabei im Site Packahe ein paar Sachen in der News anzupassen.
Wie man z.B. eigene Felder in einem neuen Flexform-Tab einfügt, habe ich jetzt auch für die 12 rausgefunden.
Ich brauche bei einer verwandten Sache einen Tipp in die richtige Richtung:
Wie kann ich in einem bestehenden Flexform-Tab ein Feld hinzufügen, damit ich auf den Wert im Fluid zugreifen kann?
Konkret möchte ich im news_pi1-Plugin im Plugin-Tab in den Plugin-Optionen im Tab "Template" ein neues Feld platzieren (s. Screenshot). Dabei möchte ich das nicht over-engineeren und mit Kanonen auf Spatzen schießen.
Momentan scheint mir dafür
ein neuer Eintrag in der Services.yaml ,
eine eigene php-Datei in EventListener und
ein eigenes XML in Configurations/FlexForms notwendig zu sein.
Sehe ich das soweit richtig oder geht das alles einfacher?
Danke!
Antwort:
Die Schwierigkeit hier ist, dass die Datenstruktur, die an das Event übergeben wird, gegenüber dem ursprünglichen Flexform XML Abweichungen enthält.
Mit folgenden Angaben funktioniert es beispielsweise bei mir:
EXT:sitepackage/Configuration/Services.yaml
:
ErHaWeb\Sitepackage\EventListener\ModifyFlexformEvent:
tags:
- name: event.listener
identifier: 'flexParsing'
event: TYPO3\CMS\Core\Configuration\Event\AfterFlexFormDataStructureParsedEvent
EXT:sitepackage/Classes/EventListener/ModifyFlexformEvent.php
:
<?php
namespace ErHaWeb\Sitepackage\EventListener;
use TYPO3\CMS\Core\Configuration\Event\AfterFlexFormDataStructureParsedEvent;
use TYPO3\CMS\Core\Utility\ArrayUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
class ModifyFlexformEvent
{
public function __invoke(AfterFlexFormDataStructureParsedEvent $event): void
{
$dataStructure = $event->getDataStructure();
$identifier = $event->getIdentifier();
// $identifier['dataStructureKey'] depends on the selected plugin!
if ($identifier['type'] === 'tca' && $identifier['tableName'] === 'tt_content' && $identifier['dataStructureKey'] === '*,news_pi1') {
$file = GeneralUtility::getFileAbsFileName('EXT:sitepackage/Configuration/FlexForms/News/Extend.xml');
$content = file_get_contents($file);
if ($content) {
ArrayUtility::mergeRecursiveWithOverrule($dataStructure, GeneralUtility::xml2array($content));
}
}
$event->setDataStructure($dataStructure);
}
}
EXT:sitepackage/Configuration/FlexForms/News/Extend.xml
:
<T3DataStructure>
<sheets>
<template>
<ROOT>
<el>
<settings.myNewField>
<label>My new Field</label>
<description>Yay! I extended the flexform of EXT:news!!!</description>
<config>
<type>select</type>
<renderType>selectSingle</renderType>
<items>
<numIndex index="0">
<label/>
<value/>
</numIndex>
<numIndex index="1">
<label>Awesome item</label>
<value>0</value>
</numIndex>
<numIndex index="2">
<label>Even more great item</label>
<value>1</value>
</numIndex>
<numIndex index="3">
<label>The best element ever</label>
<value>2</value>
</numIndex>
</items>
</config>
</settings.myNewField>
</el>
</ROOT>
</template>
</sheets>
</T3DataStructure>
Auffällig ist hier zum Beispiel, dass die einzelnen Items der Select-Box mit label
und value
benamt werden müssen. Ursache hierfür ist o.g. Abweichung.
Damit du sicher gehst, dass dein eigenes Flexform in die richtige Struktur hinein gemergt wird empfehle ich dir einmal direkt in der EXT:sitepackage/Classes/EventListener/ModifyFlexformEvent.php
eine Debug Ausgabe beider zu mergenden Arrays sowie das resultierende Array zu machen:
DebugUtility::debug($dataStructure, 'BASE DS BEFORE MERGE');
DebugUtility::debug(GeneralUtility::xml2array($content), 'DS TO MERGE');
ArrayUtility::mergeRecursiveWithOverrule($dataStructure, GeneralUtility::xml2array($content));
DebugUtility::debug($dataStructure, 'DS AFTER MERGE');
Dadurch kommt ganz gut heraus, wie dein zu mergendes "Flexform" XML unter Berücksichtigung der Abweichungen genau aussehen muss.