WordPress: Wirklich individuelle Navigation erstellen und der Walker_Nav_Menu Klasse

Es kommt immer wieder vor, dass eine Website-Navigation, nicht nur den Seitennamen anzeigen soll, sondern auch Informationen, die dazu gehören, wie zum Beispiel die Description oder das Seiten-Bild, oder was auch immer… Um die Kontrolle darüber zu bekommen, braucht man die Walker_Nav_Menu Klasse.

Vorgehensweise
In der functions.php folgenden Code eingeben, es entspricht dem WP-eigenen Code. Dort werden anschließend die gewünschten Änderungen durchgeführt.

class Custom_Walker extends Walker_Nav_Menu{

  function start_el(&$output, $item, $depth, $args){

    $classes = empty ( $item->classes ) ? array () : (array) $item->classes;
    $class_names = join(“ „, apply_filters(„nav_menu_css_class“, array_filter($classes), $item));

    ! empty ($class_names) and $class_names = “ class='“ . esc_attr($class_names) . „‚“;

    $output .= $indent . „<li id=’menu-item-“ . $item->ID . „‚“ . $value . $class_names . „>“;

    $attributes = „“;

    ! empty($item->attr_title) and $attributes .= “ title='“ . esc_attr($item->attr_title) . „‚“;
    ! empty($item->target) and $attributes .= “ target='“ . esc_attr($item->target) . „‚“;
    ! empty($item->xfn) and $attributes .= “ rel='“ . esc_attr($item->xfn) . „‚“;
    ! empty($item->url) and $attributes .= “ href='“ . esc_attr($item->url) . „‚“;

    $title = apply_filters(„the_title“, $item->title, $item->ID);

    $item_output = $args->before . „<a $attributes>“ . $args->link_before . $title . „$lt;/a> “ . $args->link_after. $args->after;

    // Since $output is called by reference we don’t need to return anything.
    $output .= apply_filters(„walker_nav_menu_start_el“, $item_output, $item, $depth, $args);
  }
}

Was wollen wir jetzt ändern? Zum Beispiel keine <ul><li>-Navigation sondern einfach <div> für die einzelnen Navigationselemente. Dazu das Artikelbild unterhalb, und die Description (aus dem Menue). Das sieht dann z. B. aus aus:

// Add these lines in order to fetch the additional information you wish to display

// We need the target page id in order to fetch the page image
$page = get_page_by_path(basename($item->url));
$page_id = $page->ID;
// We should check if there is an image set or not, but we are lazy for this example
$image_url = get_the_post_thumbnail( $page_id, ‚custom-image-preview‘ );
// Same thing for the description
$description = esc_attr( $item->description );

// Remove the li
// Instead of $item_output = $args->before . „<a $attributes>“ . $args->link_before . $title . „$lt;/a> “ . $args->link_after. $args->after;
$output .= „“;

// Change the output like you need it
$item_output = $args->before . „<div class=’container-main’><a $attributes>“ . $args->link_before . $title . „</a><div class=’page-image’>“ . $image_url . „</div><div class=’menu-page-description’>“ . $description . „</div></div> “ . $args->link_after. $args->after;

Damit es nun auch angezeigt wird, muss der Aufruf von wp_nav_menu modifiziert werden. Beispielsweise so:

wp_nav_menu( array( ‚theme_location‘ => ‚my-custom-navigation‘,
    ‚menu‘ => “,
    ‚container‘ => ’nav‘, // Auto wrap navigation in <nav> area
    ‚container_class‘ => FALSE,
    ‚container_id‘ => FALSE,
    ‚menu_class‘ => FALSE,
    ‚menu_id‘ => FALSE,
    ‚echo‘ => true,
    ‚fallback_cb‘ => ‚wp_page_menu‘,
    ‚before‘ => “,
    ‚after‘ => “,
    ‚link_before‘ => “,
    ‚link_after‘ => “,
    ‚items_wrap‘ => ‚%3$s‘, // Remove the ul container
    ‚depth‘ => 0,
    ‚walker‘ => new Custom_Walker ) );