S7
zurückGlobales Menü aus Datensätzen generiert
08.03.2019
Thema: TYPO3

Globales Menü aus Datensätzen generiert

Für eine Produktübersicht ergab sich die Notwendigkeit, ein immer vorhandenes Menü für die Webseite zu generieren.

Der erste Gedanke war, hier ein Plugin zu bauen, welches die Datensätze holt, aufbereitet und ausliefert, damit im Fluid Template das Menü generiert werden kann.

Folgende Szenarien wären damit möglich gewesen:

Ein separates Plugin auf jeder Seite einbinden

Warum nicht?

Man muss sich damit immer eine eigene Spalte im TYPO3 frei halten. Und das Plugin muss auf jeder Seite eingebunden werden.

Das Plugin mit eigenem CONTENT-Objekt einbinden

Das ist dann schon besser, man kann das Objekt dann gut über TypoScript abholen. Der Nachteil besteht aber auch hier immer noch darin, ein komplettes Plugin nur für ein Menü zu bauen und alles Extbase mitzuziehen. Außerdem kann ich mein Menü nicht im Template manipulieren.

Das Ziel ist der DatabaseQueryProcessor

Zunächst betrachtete ich also die Option, Daten mit dem DatabaseQueryProcessor zu holen.

Das hat gut funktioniert, ich hatte schnell ein Ergebnis:

10 = TYPO3\CMS\Frontend\DataProcessing\DatabaseQueryProcessor
10 {
   table = tx_sudhaus7product_domain_model_product
   pidInList = 29
   as = prod
}

Diesen Prozessor im page-Objekt unter dataProcessing eingebunden, hat mir meine Elemente schon mal sehr schön in mein Seitentemplate geladen.

Im Fluid war die Handhabe hier auch recht einfach:

<f:for each="{prod}" as="product">
    <f:link.action
        arguments="{product: '{product.data.uid}'}"
        extensionName="sudhaus7product"
        controller="Product"
        action="show"
    />
</f:for>

Spannend wurde es, auch noch die Kategorie am Produkt mit auszugeben. Auch hier half mir der Prozessor wieder, ich kann ja jedem Prozessor neue dataProcessings zuweisen:

10 = TYPO3\CMS\Frontend\DataProcessing\DatabaseQueryProcessor
10 {
   table = tx_sudhaus7product_domain_model_product
   pidInList = 29
   as = prod
   dataProcessing {
      10 = TYPO3\CMS\Frontend\DataProcessing\DatabaseQueryProcessor
      10 {
         if.isTrue.field = category
         pidInList = 29
         table = tx_sudhaus7product_domain_model_category
         selectFields = tx_sudhaus7product_domain_model_product.*
         where.data = field:uid
         where.wrap = tx_sudhaus7product_domain_model_product_category_mm.uid_local=|
         join (
                     tx_sudhaus7product_domain_model_product_category_mm on tx_sudhaus7product_domain_model_product_category_mm.uid_foreign=
                    tx_sudhaus7product_domain_model_category.uid
         )
         orderBy = tx_sudhaus7product_domain_model_product_category_mm.sorting
         as = category
      }
   }
}

Somit habe ich bei jedem Durchlauf eines Produktes die jeweils zugehörigen Kategorien noch mit dabei.

Man kann, wenn man es benötigt, natürlich erst die Kategorien und dann die Produkte durchlaufen.

Einzig eine Sache fehlt jetzt noch für ein richtiges Menü: Der Aktivzustand.

Hier bediene ich mich der Tatsache, dass jede Anfrage an ein Produkt und/oder eine Kategorie in TYPO3 nur ein GET-Aufruf ist.

Mit diesem Wissen und der Tatsache, dass der DatabaseQueryProcessor analog zu CONTENT.select in TypoScript arbeitet, ergibt sich daraus folgende Änderung im TypoScript, um zu jedem Element das active-flag zu haben:

10 = TYPO3\CMS\Frontend\DataProcessing\DatabaseQueryProcessor
10 {
   table = tx_sudhaus7product_domain_model_product
   pidInList = 29
   as = prod
   selectFields.stdWrap.cObject = COA
   selectFields.stdWrap.cObject {
      stdWrap.htmlSpecialChars = 1
      10 = TEXT
      10.value = tx_sudhaus7product_domain_model_product.*
      10.wrap = |,
      20 = TEXT
      20.value = 0
      20.override.data = gp:tx_sudhaus7product|product
      20.wrap = wrap = IF(tx_sudhaus7product_domain_model_category.uid=|, 1, 0) as active
   }
   dataProcessing {
      10 = TYPO3\CMS\Frontend\DataProcessing\DatabaseQueryProcessor
      10 {
         if.isTrue.field = category
         pidInList = 29
         table = tx_sudhaus7product_domain_model_category
         selectFields.stdWrap.cObject = COA
         selectFields.stdWrap.cObject {
            stdWrap.htmlSpecialChars = 1
            10 = TEXT
            10.value = tx_sudhaus7product_domain_model_product.*
            10.wrap = |,
            20 = TEXT
            20.value = 0
            20.override.data = gp:tx_sudhaus7product|category
            20.wrap = IF(tx_sudhaus7product_domain_model_category.uid=|, 1, 0) as active
         }
         where.data = field:uid
         where.wrap = tx_sudhaus7product_domain_model_product_category_mm.uid_local=|
         join (
                     tx_sudhaus7product_domain_model_product_category_mm on tx_sudhaus7product_domain_model_product_category_mm.uid_foreign=
                    tx_sudhaus7product_domain_model_category.uid
         )
         orderBy = tx_sudhaus7product_domain_model_product_category_mm.sorting
         as = category
      }
   }
}

Durch das Definieren des selectFields als COA und einer Überprüfung auf gesetzte GET-Parameter bekomme ich so zu jeder Kategorie und zu jedem Produkt noch das active-Flag dazu. HtmlSpecialChars sorgt dafür, dass kein XSS über die URL eingebaut werden kann.

selectFields.stdWrap.cObject = COA
selectFields.stdWrap.cObject {
   stdWrap.htmlSpecialChars = 1
   10 = TEXT
   10.value = tx_sudhaus7product_domain_model_product.*
   10.wrap = |,
   20 = TEXT
   20.value = 0
   20.override.data = gp:tx_sudhaus7product|product
   20.wrap = wrap = IF(tx_sudhaus7product_domain_model_category.uid=|, 1, 0) as active
}

Insgesamt finde ich das Menü so eine gelungene Lösung. Der Overhead durch ein Extbase-Plugin wird komplett vermieden, die Daten werden aus der Datenbank direkt geholt. Das Menü lässt sich ohne Probleme und Tricks in das Template der Seite einbinden und muss nicht im Plugin gepflegt werden.

Dank der verschachtelbaren dataProcessings kann man hier zum Beispiel auch die Produkt- oder Kategoriebilder noch mit holen und ein Kachelmenü gestalten. Somit ist auch noch eine gute Erweiterbarkeit gegeben.

Ähnliche Beiträge
16.05.2019

(DRAFT) Typo3 9.5, Extbase Models generiert im Frontend und sprechende URLs

Da ist sie, die schöne neue sprechende URL Welt in Typo3 9.5. Einfach ein Feld vom Typ 'slug' konfigurieren, und der Datensatz hat eine schöne, sprechende, SEO sichere URL. Ausser, naja, ausser der Datensatz wurde im Frontend, oder via Cron oder sonnst irgendwie in der auch so schönen Extbase Welt generiert.. Was tun?  

Uploadfilter und Leistungsschutzrecht
26.03.2019

Uploadfilter und Leistungsschutzrecht

Worum geht es?

Jetzt ist sie durch: Die EU-Richtlinie zum "Urheberrecht im digitalen Binnenmarkt" ist vom Europäischen Parlament abgesegnet worden. 348 Abgeordnete waren dafür, 274 waren dagegen, 36 enthielten sich. Der Riss ging dabei durch alle Fraktionen. Besonders umstritten sind die Artikel 15 (früher 11) und 17 (früher 13).  

TYPO3 Extensions aktualisieren
26.02.2019

Hilfe, meine TYPO3 Extension ist zu alt!

Wie hält man seine TYPO3 Erweiterungen auf dem neuesten Stand?

Jeder der TYPO3 Extensions schreibt und diese über die Jahre pflegt, kommt irgendwann mal an die Stelle, wo die Extension zu alt ist für die glänzend neue TYPO3 Version.  

Uploadfilter
22.02.2019

Uploadfilter

Worum geht es?

Nach monatelangem Tauziehen steht fest: Die Europäische Union verpflichtet künftig Webseiten und Apps zum Filtern von Inhalten. Die Freiheit im Internet schwindet damit, fürchten Netzaktivisten. Am Text der Reform ist nicht mehr zu rütteln, die endgültige Abstimmung kommt in wenigen Wochen.  

Allgemeines Gleichbehandlungsgesetz
12.02.2019

Allgemeines Gleichbehandlungsgesetz

Auswirkungen des dritten Geschlechts „divers“ auf Arbeitgeber und Personalabteilungen in der Praxis

Seit Mitte Dezember ist in Deutschland ein Gesetz in Kraft, das offiziell ein drittes Geschlecht neben Mann und Frau bestätigt. Nach dem Gesetzentwurf wird dieses mit der Bezeichnung „divers“ betitelt. Welche Auswirkungen hat diese Anerkennung des dritten Geschlechts auf Arbeitgeber sowie Personalabteilungen im Besonderen?  

World Usability Day
12.11.2018

World Usability Day 2018

Der Wert von Usability bei der User Experience

Alljährlich findet in vielen Städten der Welt der World Usability Day statt. Es gibt jede Menge Seminare, Workshops und Konferenzen, die sich umfassend mit Themen und Fragen rund um Usability und User Experience auf verschiedenen Gebieten befassen. Unsere Mitarbeiter waren in Stuttgart und Wien auf Veranstaltungen.  

ePrivacy-Verordnung
05.11.2018

Die ePrivacy-Verordnung

Worum geht es?

Nach der Europäischen Datenschutzgrundverordnung (EU-DSGVO) droht nun der nächste Schlag. Die Diskussionen um die ePrivacy-Verordnung tragen zur bereits ohnehin bestehenden Verwirrung bei. Aber worum geht da eigentlich? Und ist das überhaupt neu?  

TYPO3-Baukastensystem
02.11.2018

Unser TYPO3-Baukastensystem

Ein hochleistungsfähiges Multi-Mandantensystem

Viele flächendeckend verteilte Unternehmen und Organisationen haben die Idee und den Anspruch ihren Unternehmenseinheiten ein standardisiertes Tool in einheitlichem Look & Feel zur Verfügung zu stellen, welche innerhalb eines vorgegebenen Rahmens eine größtmögliche Flexibilität an Contentproduktions- bzw. Darstellungsmöglichkeiten haben.  

Editieren von Datensätzen
16.10.2018

Editieren von Datensätzen im Backend-Modul

Erstellung eines Links zur Editieransicht im ViewHelper oder Controller

Die TYPO3-Dokumentation zum Setzen eines Links zur Editieransicht eines Datensatzes in TYPO3 8 und 9 ist im Moment noch veraltet. Ich zeige, wie dies in Backend-Modulen, die die genannten TYPO3-Versionen als Abhängigkeit haben, tatsächlich umgesetzt werden muss.  

Kommentare