WordPress 3.0: Slug-basierte Klassen im Menü

Mit WordPress 3.0 wurde ein neues Menü-System eingeführt, das sich insbesondere bei „klassischen Webseiten“ sehr gut macht. Man kann damit im Backend einfach ein Menü zusammenklicken und dabei beliebig Seiten, Kategorien und externe Links mischen. Gestern bin ich dabei auf einen Haken gestoßen, für den auch Google nicht wirklich eine Lösung erbrachte: Die Menüpunkte sollen individuell gestylt werden, und das Standard-Menü bietet mir dafür nur ID-basierte Klassen an.

Normalerweise steht eine ID wie „menu-item-19″ und Klassen wie „menu-item menu-item-type-post_type menu-item-19″ zur Verfügung. Damit kann man arbeiten, aber das hat zwei Nachteile: Die IDs sagen sehr wenig aus und man muss dann immer als Kommentar dazuschreiben, worum es gerade geht. Und wenn man ein Testsystem hat, kann man das nicht einfach schnell parallel einrichten, sondern muss dafür sorgen, dass die IDs genau gleich sind. Schöner wären Klassen, die auf dem „Slug“ basieren, also dem für URLs bereinigten Namen. Die Seite „Über uns“ hat z.B. den Slug „ueber-uns“.

Dazu habe ich mir folgenden Code gebaut, unter Ausnutzung des Filters „nav_menu_css_class“:

/**
 * Prints an additional class on menu items with the structure
 * 'menu-item-[type]-[slug]'. The type can be 'page' or 'category'.
 * 
 * @param classes The array of classes of a menu item.
 * @param item The menu item object.
 */
function jr_nav_menu_css_class($classes, $item = '') {
  if (($item->object == 'page') || ($item->object == 'category')) {
    if (strpos($item->url, '?') !== false) {
      // there is no slug in the URL, use the ID
      $slug = $item->post_name;
    } else {
      // normal URL, try to get the slug
      $slug = end(array_filter(explode('/', $item->url)));
    }
    $classes[] = 'menu-item-' . $item->object . '-' . $slug;
  }
  return $classes;
}

add_filter('nav_menu_css_class', 'jr_nav_menu_css_class', 10, 2);

Getestet mit: WordPress 3.0

Der Code gehört in die functions.php des Themes oder in ein Funktions-Plugin. Man kann ihn sicher leicht anpassen, damit er für andere Elemente eines Menüs funktioniert. Im Moment gibt er Kategorien eine zusätzliche Klasse „menu-item-category-[slug]“ und statischen Seiten eine Klasse „menu-item-page-[slug]“.

Dabei muss man mit dem arbeiten, was das Menü-Objekt (der zweite Parameter der Filtermethode) anzubieten hat, wozu leider nicht der Slug gehört. Ich habe die Funktion deshalb derart gestaltet, dass sie für Kategorien und statische Seiten versucht, den Slug aus der URL auszulesen. Wenn diese einen Query-Teil enthält, deutet das daraufhin, dass keine umgeschriebenen Permalinks verwendet werden. Dann wird das Feld „post_name“ ausgelesen, was bei mir im Test immer die ID enthält – in der Tabelle für Posts steht dort aber der Slug drin.

Das ganze ist kurz erfolgreich getestet, aber nur im begrenzten Rahmen meines aktuellen Projekts. Über Rückmeldungen von anderen würde ich mich freuen. Bei Problemen schaue ich auch gerne, dass ich den Code-Schnipsel noch verbessert kriege.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Bitte beachte die Kommentarregeln: 1) Kein Spam, und bitte höflich bleiben. 2) Ins Namensfeld gehört ein Name. Gerne ein Pseudonym, aber bitte keine Keywords. 3) Keine kommerziellen Links, außer es hat Bezug zum Beitrag. mehr Details...

So, noch mal kurz drüber schauen und dann nichts wie ab damit. Vielen Dank fürs Kommentieren! :-)