Fügen Sie einem in einem Widget erstellten Menü einen benutzerdefinierten Walker hinzu


10

Ich weiß, wie man einen Walker zu einem benutzerdefinierten Menü hinzufügt, das vom Thema erstellt wurde ( primaryin diesem Beispiel genanntes Menü ), aber wie kann ich ein Menü, das in einem Widget erstellt wurde, mit dem Standard-Widget für benutzerdefinierte WordPress-Menüs ausrichten?

if ( has_nav_menu( 'primary' ) ) {

$args = array(
    'menu' => 'main-menu',
    'menu_id' => 'main-menu',
    'theme_location' => 'primary',
    'depth' => 0,
    'container' => false,
    'menu_class' => 'nav',
    'walker' => new Myprefix_Walker_Nav_Menu(),
    'echo' => 0
);

$nav = wp_nav_menu( $args );

}

Antworten:


14

Wenn Sie sich die Implementierung der WP_Nav_Menu_WidgetKlasse ansehen, sehen Sie den folgenden Code:

function widget($args, $instance) {
    // Get menu
    $nav_menu = ! empty( $instance['nav_menu'] ) ? wp_get_nav_menu_object( $instance['nav_menu'] ) : false;

    if ( !$nav_menu )
        return;

    $instance['title'] = apply_filters( 'widget_title', empty( $instance['title'] ) ? '' : $instance['title'], $instance, $this->id_base );

    echo $args['before_widget'];

    if ( !empty($instance['title']) )
        echo $args['before_title'] . $instance['title'] . $args['after_title'];

    wp_nav_menu( array( 'fallback_cb' => '', 'menu' => $nav_menu ) );

    echo $args['after_widget'];
}

Dies bedeutet, dass es keine Möglichkeit gibt, ein Menü zu verknüpfen. Sie müssen sich also die wp_nav_menuFunktionsimplementierung ansehen , in der Sie folgende Codezeilen finden:

$defaults = array(
  'menu' => '',
  'container' => 'div',
  'container_class' => '',
  'container_id' => '',
  'menu_class' => 'menu',
  'menu_id' => '',
  'echo' => true,
  'fallback_cb' => 'wp_page_menu',
  'before' => '',
  'after' => '',
  'link_before' => '',
  'link_after' => '',
  'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s</ul>',
  'depth' => 0,
  'walker' => '',
  'theme_location' => ''
);

$args = wp_parse_args( $args, $defaults );
$args = apply_filters( 'wp_nav_menu_args', $args );
$args = (object) $args;

Hier sehen Sie, dass alle an die wp_nav_menuFunktion übergebenen Argumente ersetzt werden konnten. Sie müssen also Ihren eigenen Hook-Handler erstellen, der Ihren Walker zu einem Navigationsmenü hinzufügt. Es könnte einfach sein als:

function myplugin_custom_walker( $args ) {
    return array_merge( $args, array(
        'walker' => new My_Custom_Walker(),
        // another setting go here ... 
    ) );
}
add_filter( 'wp_nav_menu_args', 'myplugin_custom_walker' );

Das ist großartig, danke. Sieht so aus, als ob dies die Standardeinstellung für alle Menüs ist. Habe ich Recht anzunehmen, dass ich, wenn ich dies benutze, bei allen Menüs mit diesem Walker festgefahren bin? weil ich 'walker' => new Walker_Nav_Menu()in den Argumenten meines spezifischen Menüs versucht habe, es erneut zu überschreiben, um der WordPress-Standard-Walker für nur ein Menü zu werden, aber leider funktioniert dies nicht.
Amy

@amy Ja, es wird die Standardeinstellung für alle Menüs sein.
Eugene Manuilov

@amy Sie können Code einschließen, um die Argumente zu untersuchen. Geben Sie dann eine if-Bedingung an, ob Sie den Walker anwenden oder nicht.
Wayne

4

Wenn Sie die Antwort von @ Eugene erweitern und dies auf ein bestimmtes Menü beschränken möchten, überprüfen Sie einfach die Term-ID des Menüs:

function custom_nav_args($args){
$menu = $args['menu'];
    if($menu->term_id === 17)  /* replace term_id with menu id, or use $menu->name to do it by menu name*/
    {
        $args['walker'] = new My_Custom_Walker();
    }
    return $args;
}
add_filter('wp_nav_menu_args', 'custom_nav_args');

Wie würden wir nach Seitenleisten-ID filtern?
Steven Vachon

1

Dies ist eine Alternative zum Targeting eines Menüs von term_idund ich dachte, es könnte für jemanden von Nutzen sein, um mehrere Menüs zu ändern, ohne deren IDs nachschlagen zu müssen.

Beim Hinzufügen print_r($args)zu einem Filter habe ich festgestellt, dass dies $args['menu']eine Zeichenfolge für Menüs an vordefinierten Themenpositionen und WP_Term_Objectfür ein benutzerdefiniertes Menü-Widget in einer Seitenleiste ist.

Ich habe dies verwendet, um Menüs per Slug anzuvisieren und ihrem Container eine Klasse hinzuzufügen. Eine Reihe von Menüs kann als Ziel ausgewählt werden, indem eine gemeinsame Zeichenfolge in ihre Slugs eingefügt wird. Hinweis: Der Menü-Slug kommt von der Array-Eingabe register_nav_menus().

function my_menu_thingy( $args ) {
  if( is_object($args['menu']) && strpos($args['menu']->{slug},'my-common-string') !== false ) {
    $args['walker'] = new My_Custom_Walker();
  }
  return $args;
}
add_filter( 'wp_nav_menu_args', 'my_menu_thingy' );

Für ein einzelnes Menü müssten Sie dies nur $args['menu']->{slug} == 'your-slug'anstelle des obigen strpos () - Bits überprüfen .


1

Sie können einem in einem Widget erstellten Navigationsmenü mithilfe des widget_nav_menu_argsin WordPress hinzugefügten Filters einen benutzerdefinierten Walker hinzufügen 4.2.0. Es akzeptiert vier Argumente (siehe wp-includes/widgets/class-wp-nav-menu-widget.php). Um jedoch nur einen benutzerdefinierten Walker hinzuzufügen, müssen Sie nur das erste Argument verwenden, genauso wie Sie den wp_nav_menu_argsFilter verwenden.

    add_filter('wp_nav_menu_args', 'my_args'); //for menus
    add_filter('widget_nav_menu_args', 'my_args'); //for menus in widgets
    function my_args($args) { //$args is only argument needed to add custom walker
       return array_merge( $args, array(
          'walker' => new My_Custom_Walker(),
       ) );
    }
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.