Wenn man mit Gridelements und somit verschachtelten Inhaltselementen arbeitet, stellt man vielleicht irgendwann fest, dass die Sortierung nicht funktioniert, sobald in der Abschnittsnavigation anzuzeigende Inhaltselemente in Container (2-Spalten etc.) angeordnet werden. Beispiel (in Klammern ist die Position intern):
- Container A (1)
- Element A.1 (1)
- Element A.2 (2)
- Container B (2)
- Element B.1 (1)
- Element B.2 (2)
Je nachdem, in welcher Reihenfolge man die Elemente erstellt hat, kann z.B. folgende Abschnittsnavigation ausgegeben werden:
- B.1
- A.1
- A.2
- B.2
Ich habe z.B. folgende Lösung mit einem ViewHelper gefunden. Ich wollte jedoch eine Lösung, die auch für bereits vorhandene Inhaltselemente funktioniert und die unabhängig vom Template eingesetzt werden kann. So habe ich mich für einen DataProcessor entschieden.
Als erstes hole ich mir alle Inhaltselemente – unabhängig davon, ob sectionIndex gesetzt ist oder nicht. Dann hänge ich meinen eigenen DataProcessor ein.
tt_content.menu_section.dataProcessing.10.dataProcessing.20 { where > } tt_content.menu_section.dataProcessing.10.dataProcessing.30 = NP\MyExtension\DataProcessing\SectionProcessor
Im DataProcessor werden die Datensätze gefiltert, so dass nur die mit sectionIndex = 1 übrig bleiben. Weiterhin wird die Sortierung korrigiert und es wird neu sortiert. Beim neuen Sorting wird der Wert der Elemente, die direkt auf der Seite abgelegt sind, mit 10000 multipliziert. Falls das Element in einem Container liegt, dann wird die Sortierung auf den Sorting-Wert des Containers mal 10000 plus die eigene Sortierung gesetzt.
Den DataProcessor lege ich unter Classes\DataProcessing\SectionProcessor.php ab:
namespace NP\MyExtension\DataProcessing; use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface; class SectionProcessor implements DataProcessorInterface { /** * Process content object data * * @param ContentObjectRenderer $cObj The data of the content element or page * @param array $contentObjectConfiguration The configuration of Content Object * @param array $processorConfiguration The configuration of this processor * @param array $processedData Key/value store of processed data (e.g. to be passed to a Fluid View) * @return array the processed data as key/value store */ public function process( ContentObjectRenderer $cObj, array $contentObjectConfiguration, array $processorConfiguration, array $processedData ) { $processedContent = []; $sortMapping = []; foreach ($processedData['content'] as $content) { if ($content['data']['sectionIndex'] == 1) { $content['data']['sorting'] = $this->getRealSorting($content, $processedData['content']); $processedContent[] = $content; } } // debug($processedContent, 'processed content'); usort($processedContent, [$this, 'sortContent']); $processedData['content'] = $processedContent; return $processedData; } /** * @param array $content * @param array $allElements */ protected function getRealSorting($content, $allElements) { if ($content['data']['colPos'] != '-1') { return $content['data']['sorting'] * 10000; } $sorting = $content['data']['sorting']; foreach ($allElements as $element) { if ($element['data']['uid'] == $content['data']['tx_gridelements_container']) { $sorting += $element['data']['sorting'] * 10000; } } return $sorting; } /** * @param array $a * @param array $b * @return bool */ protected function sortContent($a, $b) { return $a['data']['sorting'] > $b['data']['sorting']; } }
Dieser Ansatz wird limitiert durch das Verschachtelungslevel der Elemente. Da könnte man diesen auf die schnelle implementierten Ansatz noch optimieren.
Neueste Kommentare