TYPO3 8 Menüs mit Fluid und MenuProcessor erstellen

Über viele Jahre wurden Menü Strukturen in TYPO3 mit TypoScript erstellt. Wer viel mit Fluid Templates arbeitet wird feststellen das letzte Html, welches aus TypoScript kommt, sind die Menüs sind. Mit dem in TYPO3 8.7 LTS eingeführten MenuProcessor und eigenen Templates lässt sich da gut und flexibel Abhilfe schaffen.

MenuProcessor

Der MenuProcessor ist einer der neuen DataProcessoren und gibt ein gut auswertbares Menü Array and das Fluid Template weiter. Der Inhalte des Arrays ist über umfangreiche Optionen gut zu beeinflussen. Die meisten Einstellungen sind identisch zum TypoScript HMENU Objekt.

Erlaubte Settings vom HMENU:

cache_period, entryLevel, special, minItems, maxItems, begin, alternativeSortingField, excludeUidList, excludeDoktypes, includeNotInMenu, alwaysActivePIDlist, protectLvar, addQueryString, if, levels, expandAll, titleField

Prozessor spezifisch sind:

as, includeSpacer, dataProcessing

Ein paar Defaults gibt es auch:

levels = 1
expandAll = 1
includeSpacer = 0
as = menu
titleField = nav_title // title

Menu Item Array

Der Menü Prozessor gibt für jede Seite im Menü ein Array mit folgenden Elementen zurück. Abhängig vom Menü Typ können diese unterschiedlich sein. Standard ist:

data = array mit allen Eigenschaften der Seite (Page Object)
title = Titel oder Navigationstitel der Seite
link = Link zur Seite
target = Linkziel
active = True wenn die Seite im aktiven Menü Zweig ist
current = True wenn es die aktive Seite ist
spacer = True wenn die Seite ein Menü Trenner ist
children = array der Unterseite wenn welche vorhanden sind

TypoScript Settings

Die Menü Objekte werden im page Objekt unter dataProcessing erstellt. Ein Beispiel aus dem Feature: #78672.

10 = TYPO3\CMS\Frontend\DataProcessing\MenuProcessor
10 {
   special = list
   special.value.field = pages
   levels = 7
   as = menu
   expandAll = 1
   includeSpacer = 1
   titleField = nav_title // title
   dataProcessing {
      10 = TYPO3\CMS\Frontend\DataProcessing\FilesProcessor
      10 {
         references.fieldName = media
      }
   }
}

Die Spezialität dieses Skripts ist es das die Dateien aus dem Ressourcen/Media Feld der Seite mit übergeben werden und im Template verwendet werden können.
Eingebunden wird das ganze normalerweise im Fluidtemplate unter page.10.dataProcessing.

Hauptmenü mit Dropdown

Das Menü besteht aus dem TypoScript für die Bereitstellung der Daten und dem Template. Die Klassen für das Menü sind für das Styling mit Zurb Foundation 6 benannt, können aber einfach an andere CSS Frameworks angepasst werden.

TypoScript einfach:

10 = TYPO3\CMS\Frontend\DataProcessing\MenuProcessor
10 {
  levels = 6
  as = menuMain
}

TypoScript mit Startverzeichnis und Trenner:

10 = TYPO3\CMS\Frontend\DataProcessing\MenuProcessor
10 {
  special = directory
  special.value = 1
  levels = 6
  includeSpacer = 1
  as = menuMain
}

Die Templates liegen bei mir im Partials Ordner unter Navigation. Um sie übersichtlich zu halten, gibt es extra Templates für den einzelnen Menü Eintrag und den Link.

Template erste Ebene:

<f:if condition="{menuMain}">
	<ul class="vertical medium-horizontal menu" data-responsive-menu="accordion medium-dropdown">
		<f:for each="{menuMain}" as="mainItem">
			<f:render partial="Navigation/Elements/Item" arguments="{item: mainItem}"/>
			<f:if condition="{mainItem.children}">
				<f:render section="submenu" arguments="{submenu: mainItem.children}"/>
			</f:if>
			</li>
		</f:for>
	</ul>
</f:if>

Wenn der Menü Eintrag Unterseiten (ifSub) enthält wird die submenu Section gerendert.

<f:section name="submenu">
	<ul class="vertical menu">
		<f:for each="{submenu}" as="subItem">
			<f:render partial="Navigation/Elements/Item" arguments="{item: subItem}"/>
			<f:if condition="{subItem.children}">
				<f:render section="submenu" arguments="{submenu: subItem.children}"/>
			</f:if>
			</li>
		</f:for>
	</ul>
</f:section>

Im Item Partial wird berücksichtigt, ob für das Menü Element die Eigenschaften active, current oder spacer gesetzt sind.

<f:if condition="{item.spacer} || {item.current}">
	<f:then>
		<li class="{f:if(condition:item.current, then:' current')}{f:if(condition:item.spacer, then:' spacer')}">
		<span>{item.title}</span>
	</f:then>
	<f:else if="{item.active}">
		<li class="{f:if(condition:item.active, then:' active')}">
			<f:render partial="Navigation/Elements/Link" arguments="{item: item}"/>
	</f:else>
	<f:else>
		<li>
			<f:render partial="Navigation/Elements/Link" arguments="{item: item}"/>
	</f:else>
</f:if>

Im Partial für den Link werden die verschiedenen Möglichkeiten für das Link Ziel berücksichtigt.

<f:if condition="{item.data.target}">
	<f:then>
		<a href="{item.link}" target="{item.data.target}" title="{item.data.title}">
	</f:then>
	<f:else if="{item.target}">
		<a href="{item.link}" target="{item.target}" title="{item.data.title}">
	</f:else>
	<f:else>
		<a href="{item.link}" title="{item.data.title}">
	</f:else>
</f:if>
<span>{item.title}</span>
</a>

Meta Menü

Diese Menü wird häufig für Dinge wie Kontakt und Impressum verwendet. Die Page IDs für das Listen Menü kommen aus den Konstanten im Root.

20 = TYPO3\CMS\Frontend\DataProcessing\MenuProcessor
20 {
  special = list
  special.value = {$template.pidMeta}
  levels = 1
  as = menuMeta
}

Das Template ist sehr übersichtlich da die Partials für Item und Link wieder verwendet werden.

<f:if condition="{menuMeta}">
	<ul class="menu-meta menu">
		<f:for each="{menuMeta}" as="item">
			<f:render partial="Navigation/Elements/Item" arguments="{item: item}"/>
		</f:for>
	</ul>
</f:if>

Sub Menü

In diesem Fall gibt es die Unterseiten der jeweiligen Hauptkategorie aus. Mit entryLevel = -1 nur die Unterseiten der aktuellen Seite. Das Template ist mit dem Haupt Menü nahezu identisch, nur das TypoScript ist anders.

TypoScript

30 = TYPO3\CMS\Frontend\DataProcessing\MenuProcessor
30 {
  levels = 4
  entryLevel = 1
  expandAll = 0
  includeSpacer = 1
  as = menuSub
}

Template

<f:if condition="{menuSub}">
	<ul class="vertical menu menu-sub">
		<f:for each="{menuSub}" as="mainItem">
			<f:render partial="Navigation/Elements/Item" arguments="{item: mainItem}"/>
			<f:if condition="{mainItem.children}">
				<f:render section="submenu" arguments="{submenu: mainItem.children}"/>
			</f:if>
			</li>
		</f:for>
	</ul>
</f:if>

<f:section name="submenu">
	<ul class="nested vertical menu">
		<f:for each="{submenu}" as="subItem">
			<f:render partial="Navigation/Elements/Item" arguments="{item: subItem}"/>
			<f:if condition="{subItem.children}">
				<f:render section="submenu" arguments="{submenu: subItem.children}"/>
			</f:if>
			</li>
		</f:for>
	</ul>
</f:section>

Sprach Menü

Wenn das Menü vom Typ language ist, werden pro Eintrag zusätzlich die Eigenschaften available und languageUid ausgegeben. Wenn available gesetzt ist gibt es die aktuelle Seite in der gewünschten Sprache.

TypoScript

40 = TYPO3\CMS\Frontend\DataProcessing\MenuProcessor
40 {
  special = language
  special.value = {$template.languages}
  as = menuLanguage
}

Das Template ist etwas umfangreicher und sollte für die verwendeten Sprachen angepasst werden.

<f:if condition="{menuLanguage}">
	<ul id="language_menu" class="menu-language">
		<f:for each="{menuLanguage}" as="item">
			<li class="{f:if(condition: item.active, then: 'active')} {f:if(condition: item.available, else: 'text-muted')}">
				<f:switch expression="{item.languageUid}">
					<f:case value="1">
						<f:variable name="languageTitle">En</f:variable>
						<f:variable name="hreflang">en-GB</f:variable>
					</f:case>
					<f:defaultCase>
						<f:variable name="languageTitle">De</f:variable>
						<f:variable name="hreflang">de-DE</f:variable>
					</f:defaultCase>
				</f:switch>
				<f:if condition="{item.available}">
					<f:then>
						<a href="{item.link}" hreflang="{hreflang}" title="{languageTitle}">
							<span>{languageTitle}</span>
						</a>
					</f:then>
					<f:else>
						<span>{languageTitle}</span>
					</f:else>
				</f:if>
			</li>
		</f:for>
	</ul>
</f:if>

Breadcrumb Menu

Dieses Menü basiert auf dem Menü Typ rootline. Die Formatierung erfolg mit Foundation Standards.

50 = TYPO3\CMS\Frontend\DataProcessing\MenuProcessor
50 {
  special = rootline
  special.range = 0|-1
  includeNotInMenu = 1
  as = menuBreadcrumb
}

Template

<f:if condition="{menuBreadcrumb}">
	<ul class="menu-breadcrumb breadcrumbs">
		<f:for each="{menuBreadcrumb}" as="item">
			<f:render partial="Navigation/Elements/Item" arguments="{item: item}"/>
		</f:for>
	</ul>
</f:if>
Artikel Suchen
Keine Kategorien verfügbar.