TYPO3 Navigation mit VHS Viewhelper und Fluid

Neben der Einbindung einer TypoScript Library gibt es die Möglichkeit, eine Navigation über den VHS Viewhelper zu gestalten. Die Einbindung erfolgt dann nicht über TypoScript, sondern als Fluid Template.

Der große Vorteil der Arbeit mit dem VHS Viewhelper ist natürlich, dass man die Logik nutzen kann, die in die Fluid Templating Engine eingebaut ist. Damit lassen sich z. B. sehr einfach if ... else Abfragen integrieren, um unterschiedliche Zustände der Navigation zu schalten. So ist auch die Navigation in dieser Webseite aufgebaut - je nachdem, wie viele folgenden Ebenen eine Seite der zweiten Hierarchiestufe hat, wird ein Bild dargestellt oder die folgenden Links. All dies lässt sich über Fluid Conditions regeln.

Mega Menu als Vorteil für Besucher und Marketing

Ein Mega Menu bietet sowohl dem Besucher als auch dem Marketing einer Webseite gewaltige Vorteile:

  • In der Navigation sind nicht nur einzelne Links sichtbar
  • Mehrere Ebenen der Navigation können auf einen Blick dargestellt werden
  • Neben den reinen Links können weitere Informationen wie kurze Texte oder Bilder zu einem Navigationspunkt gestaltet werden
  • Einzelne besondere Punkte (z. B. Kontakt oder Sonderangebote) können in der Navigation hervorgehoben werden
  • Die Navigation ist responsiv und kann mit diesen Vorteilen sowohl auf Smartphone und Tablet als auch auf dem PC genutzt werden

Diese Gestaltungsmöglichkeiten lassen sich mit einem Framework wie Bootstrap 4 umsetzen. TYPO bietet zwei Möglichkeiten, eine solche Navigation umzusetzen: 

Wo liegen nun die Vorteile der beiden Lösungen?

  • Bei dem Aufbau einer Navigation mit TypoScript hat man den gesamten Code des Projektes unter eigener Kontrolle und ist unabhängig von der Einbindung einer Extension
  • Bei der Nutzung des VHS Viewhelpers kann man die Logik bieten, die Fluid mit sich bringt -  in erster Linie Conditions für unterschiedliche Darstellungen in derselben Ebene und Schleifen für die Staffelung mehrerer Ebenen
  • Die gesamte Navigation findet in einem Fluid Template oder Partial Platz - bei TypoScript ist es meist notwendig, eine TypoScript Datei zu erzeugen, die dort stehende Funktion per @import ins System zu laden und dann in ein Fluid Template oder Partial einzubinden

Auf dieser Seite behandeln wir den Aufbau eines Mega Menu mit dem VHS Viewhelper.

Aufbau eines Fluid Template für den VHS Viewhelper

Die Einbindung eines VHS Viewhelper in ein Fluid Template geschieht recht einfach am Beginn der Datei durch die Integration des Namespaces für den Viewhelper:

{namespace v=FluidTYPO3\Vhs\ViewHelpers}

Danach bauen Sie das gesamte Fluid Template für die Navigation auf.

Bootstrap Fluid Template für die Navigation

Der eigentliche Code für den VHS Viewhelper schachtelt man im Allgemeinen in ein HTML-Konstrukt, das Funktionen für den Aufbau der Navigation bereitstellt. Oft kommt dafür das Bootstrap Framework zum Einsatz. In der Version Bootstrap 4 bietet dieses CSS- und JavaScript Framework zahlreiche Möglichkeiten zum Aufbau einer responsiven Navigation, auch für den Einsatz eines Mega Menus wie in dieser Webseite.

Hier nun ein Beispiel für den Mantel an HTML zum Aufbau eines Mega Menus: 

 <div class="row navigation-top">
    <div class="col-12 nav-container">
        <nav class="navbar navbar-expand-lg navbar-light bg-light">
        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbar" aria-controls="navbars" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>                
            <div class="collapse navbar-collapse" id="navbar">
                <ul class="navbar-nav mr-auto"> 
                  [...hier der Code des VHS Viewhelpers...]
                </ul>
            </div>
        </nav>
    </div>
</div>

Damit steht das Grundgerüst, in das nun der Code für den VHS Viewhelper eingebaut werden kann.

Navigation mit dem VHS Viewhelper

In dieses Gerüst zum Aufbau eines Fluid Templates hängt man nun die eigentliche Navigation ein. Damit kommt der VHS Viewhelper zum Einsatz. Die Idee hinter dem Aufbau der Navigation ist, dass man für jede Ebene der Navigation Schleifen für die vorhandenen Objekte aufbaut. Wenn sich in diesen Objekten, also den einzelnen Menupunkten der jeweiligen Ebene, weitere Seiten der folgenden Ebene befinden, durchläuft man für diese jeweils eine weitere Schleife. In diesem Beispiel sind zwei Ebenen der Navigation dargestellt:

 <v:menu expandAll="1" entryLevel="0" levels="2" classHasSubpages="active" as="menuLevel1" excludePages="75">
    <f:for each="{menuLevel1}" as="menuLevel1Item">
        <li class="nav-item dropdown megamenu-li">
            <a class="nav-link dropdown-toggle" href="" id="dropdown{menuLevel1Item.uid}" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{menuLevel1Item.title}</a>
            <div class="dropdown-menu megamenu" aria-labelledby="dropdown{menuLevel1Item.uid}">
                <div class="row">
                    <!-- Menu 2. Ebene ANFANG -->
                    <v:menu pageUid="{menuLevel1Item.uid}" expandAll="1" entryLevel="1"  as="menuLevel2">
                        <f:for each="{menuLevel2}" as="menuLevel2Item">
                            <div class="col-lg-3 col-md-3 col-sm-4 col-xs-12 div-nav">
                                <f:link.page pageUid="{menuLevel2Item.uid}" title="{menuLevel2Item.linktext}" class="link-level3 strong">{menuLevel2Item.title}</f:link.page>
                            </div>
                        </f:for>
                    </v:menu>
                    <!-- Menu 2. Ebene ENDE -->
                </div>
            </div>
        </li>
    </f:for>
</v:menu>

If Condition in Navigation mit VHS Viewhelper

Der große Vorteil des Einsatzes von Fluid beim Aufbau einer Navigation für die Webseite ist es natürlich, dass man die Logik des Frameworks nutzen kann. So ist es einfach möglich, mit Conditions zu arbeiten. So kann man abfragen, ob ein bestimmtes Element vorhanden ist und danach entscheiden, welche Inhalte dargestellt werden sollen.

Hier ein Beispiel für eine solche Condition in Fluid:

 <f:if condition="{menuLevel2Item.hasSubPages}">
    <f:then>
        <v:menu pageUid="{menuLevel2Item.uid}" expandAll="1" entryLevel="1"  as="menuLevel3">
            <f:for each="{menuLevel3}" as="menuLevel3Item">
                <div class="row">
                    <div class="col-12 nav-level3">
                        <f:link.page pageUid="{menuLevel3Item.uid}" class="link-level3" title="{menuLevel3Item.linktext}">&#9656;{menuLevel3Item.title}</f:link.page>
                        [...hier Code für die 3. Ebene...]
                    </div>
                </div>
            </f:for>
        </v:menu>
    </f:then>
    <f:else>
        <v:page.resources.fal table="pages" field="media" uid="{menuLevel2Item.uid}" as="images" limit="1" slide="-1" >
            <f:if condition="{images}">
                <f:for each="{images}" as="image">
                    <div class="row">
                        <div class="col-12 nav-level3-img">
                            <f:link.page pageUid="{menuLevel2Item.uid}" title="{menuLevel2Item.linktext}">
                                <f:image src="{image.url}" alt="{image.alternative} {image.name}" title="{image.title}" maxWidth="400" class="image-embed-item" />
                            </f:link.page>
                        </div>
                    </div>
                </f:for>
            </f:if>
        </v:page.resources.fal>                        
    </f:else>
</f:if>

In diesem Beispiel erfolgt eine Abfrage, ob die zweite Ebene der Navigation noch eine folgende Ebene hat. Ist dies der Fall (then Condition), so wird der Code für die dritte Ebene geladen. Wenn dies nicht der Fall (else Condition) ist, dann wird ein Bild dargestellt.

Sichtbarkeit in Navigation mit VHS Viewhelper steuern

Wer kennt das nicht: Wir wollen in unserer Webseite bestimmte Seiten in der Navigation des Mega Menu nicht darstellen. Gründe dafür gibt es viele – einer dafür ist, dass das Tool zur Überprüfung der SEO Qualitäten der Webseite darüber meckert, das man zu viele interne Links hat. Also wirft man ein paar davon, die das Mega Menu aufblähen, aber keinen großen Mehrwert für die Suchmaschinenoptimierung haben, einfach raus. 

Das Backend von TYPO3 bietet zu diesem Zweck für einzelne Seiten in den Seiteneigenschaften die hervorragende Option an, im Reiter "Zugriff" die Seite sichtbar zu schalten, aber diese nicht in der Navigation darzustellen. Diese Links sind dann über Accordion Menus oder andere Verlinkungen noch erreichbar, aber eben nicht über das Mega Menu. Der große Nachteil: Diese Seiten sind auch nicht in den Menus in Inhaltselementen und nicht in der Breadcrumb Navigation erreichbar. Und das möchten wir vielleicht beides behalten. 

Doch auch hier bietet TYPO3 eine Lösung an, und dazu können wir TypoScript oder den VHS Viewhelper nutzen. Am Ende wird die gleiche Technik angesprochen, der Code ist unterschiedlich. 

Der Trick ist nun folgender: Wir schalten alle Seiten, die wir im Mega Menu nicht sehen, wohl aber in der Brotkrümelnavigation, auf sichtbar. Wir merken uns aber die IDs dieser Seiten, denn im Mega Menu oder in der Navbar können wir diese Seiten gezielt abschalten. 

Im TypoScript haben wir dazu dazu diesen Quellcode: 

excludeUidList = 74, 75

Im VHS Viewhelper können das Attribut excludePages nutzen: 

 <v:menu entryLevel="0" levels="2" excludePages="74">
  [...weitere Angaben...]
</v:menu>

Wir können auch mehrere Seiten als Komma-separierte Liste ausschließen: 

 <v:menu entryLevel="0" levels="2" excludePages="74, 75, 76">
  [...weitere Angaben...]
</v:menu>

Sollten Sie das Kapitel, in den Sie Seiten abgeschaltet haben, dürfen Sie natürlich nicht vergessen, die neuen IDs hinzuzufügen. Eine Abschaltung in der nächst höheren Ebene der Navigation ist nicht zu empfehlen, weil dieser Punkt dann ebenfalls aus der Navigation verschwindet.