Menü für responsive Websites mit TYPO3 und jQuery mmenu

Das mmenu ist eine schicke Sache, die wenig Wünsche übrig lässt bezüglich eines sinnvollen, hinreichend coolen und gut zu bedienenden responsive Menüs.

Achtung: diese mmenu Konfiguration bezieht sich auf eine veraltete Version. Für eine aktuelle Version (8.4.1) bitte diesen Beitrag beachten.

Die hier beschriebene Konfiguration bezieht sich auf folgende Optionen:

  • zum Einsatz kommt das CMS TYPO3
  • das responsive Menü (verfügbar über einen „Hamburger“) soll nur bis zu einer bestimmten Größe angezeigt werden, also nicht auf der Desktop und nicht auf der Tablet Landscape Version.

Zunächst lädt man sich die erforderlichen Sourcen hier herunter. Aus dem Verzeichnis dist/core/css benötigt man die Datei jquery.mmenu.all.css sowie aus dem Verzeichnis dist/core/js die Datei jquery.mmenu.min.js. Beide Dateien werden in das TYPO3 Projekt eingebunden. Selbstverständlich muss auch die jQuery Bibliothek vorhanden sein.

Mmenu benötigt korrekt verschachtelte Listenelemente. Folgendes TypoScript kann für die Generierung des Menüs zum Einsatz kommen:

lib.menu = HMENU
lib.menu.wrap = <nav id="menu">|</nav>
lib.menu.1 = TMENU
lib.menu.1 { 
  expAll = 1 
  wrap = <ul>|</ul>
  NO { 
    wrapItemAndSub = <li>|</li>
  } 
  CUR = 1 
  CUR { 
    wrapItemAndSub = <li class="Selected">|</li>
  } 
} 
lib.menu.2 < .lib.menu.1
lib.menu.3 < .lib.menu.1
lib.menu.4 < .lib.menu.1

Die Sache mit dem Selected ist wichtig, da mmenu sonst bei jedem Öffnen des Menüs die Rootseiten anzeigen würde. Wenn man sich auf einer Unterseite befindet, hat man es aber lieber, dass die jeweilige Menübene angezeigt wird – eben das gelingt, wenn das li des aktiven Menüpunkts die Klasse Selected hat.

Der Hamburger, der das mobile Menü öffnen soll, wird mit Hilfe von Font Awesome zum Beispiel so generiert:

<div id="mmenu">	 	
  <a href="#menu"><i class="fa fa-bars" aria-hidden="true"></i></a>	 	 
</div>

Schön sind auch animierte Hamburger.

Wichtig ist also, dass das href als Wert die id des nav Elements bekommt, quasi ein Ankerlink.
Da wir das Hamburger Menü nur bis zu einer bestimmten Größe des Monitors anzeigen wollen, verwenden wir etwa folgendes CSS:

@media (min-width: 769px) {
  #mmenu {
    display:none;
  }
}

Und das Menü, das in der Desktop Variante angezeigt wird, muss mobil versteckt werden, z.B. so:

@media (max-width: 768px) {
  nav#menu {
    display:none;
  }
}

Im Grunde fehlt jetzt nur noch der JavaScript Aufruf:

$(document).ready(function() {
  $("#menu").mmenu({
    // options, z.B.:
    navbar: {title:"Menü"}
  }, {
    // configuration
    clone:true
  });
});

Wichtig in unserem Zusammenhang ist clone:true, das, wie oben vorausgesetzt, dann zum Einsatz kommen muss, wenn es zwei Menüs gibt: eines für die Desktop Version und eines für die mobile Version. Hat man das Menü auf diese Art geklont, kann man die Desktop Variante bequem und einfach per CSS ausblenden.

Suchfeld im mmenu

Möchte man eine Suche im Ausklappmenü anbieten, kann man das Addon ’searchfield‘ einbinden. Allerdings wird dann lediglich das Menü durchsucht, was in den meisten Fällen nicht besonders hilfreich sein dürfte.
Vielmehr wird man vermutlich ein Suchfeld haben wollen, das die komplette Website durchsucht, was in TYPO3 meist mit Hilfe von indexed_search geschieht.
Gesetzt man hat indexed_search im Einsatz und z.B. im Header der Website das Such-Formular eingebunden

<form method="post" id="tx_indexedsearch" action="suche/?tx_indexedsearch_pi2%5Baction%5D=search&amp;tx_indexedsearch_pi2%5Bcontroller%5D=Search" >
...
</form>

dann ist die Aufgabe, dieses Form-Element in das mmenu zu bringen. Dazu gibt es zwei Möglichkeiten. In jedem Fall benötigt man das Addon navbars.
Entweder so:

var mmsuchfeld = $("#tx_indexedsearch").clone();
$(mmsuchfeld).attr("id","mmsearch");
 
$("#menu").mmenu({
  ...
  navbars : [
    ...
    ,{
       position: "bottom",
       height: 2,
       content: [
          mmsuchfeld
       ]
    }
  ]
})

oder so:

$("#menu").mmenu({
  ...
   navbars: [
     {
       position: "bottom",
       content: [
          "<div class='menu-footer'></div>"
       ]
     },
  ...
});
 
// weitere Inhalte ins Menue kopieren
var api = $('#menu').data('mmenu');
api.bind('open', function () {
  $('.menu-footer').html( $('#tx_indexedsearch').clone().html() );
});

Fallstricke:

Mit

config.prefixLocalAnchors = all

ergibt sich das Problem, dass der Ankerlink zum Menü umgeschrieben wird, mithin funktioniert das Menü nicht. Einzige, derzeitige Lösung: config.prefixLocalAnchors = all ausschalten.

Etliche weitere Optionen sowie Plugins fürs Styling findet man auf der Website des Entwicklers – ebenso auch den Hinweis, dass eine geringfügige Zahlung erforderlich ist, wenn man das Plugin im kommerziellen Bereich einsetzen möchte.