Custom Walker: cómo obtener ID en la función start_lvl

14

Estoy haciendo mi primer andador personalizado para crear un menú de acordeón. Para empezar utilicé este ejemplo: http://bitacre.com/2025/custom-nav-menu-walker-for-wordpress-themes

Hay dos funciones Primero start_lvl y luego start_el.

En start_el, el ID se implementa mediante $ item-> ID. ¿Alguien sabe cómo puedo hacer esto en start_lvl también? Necesito darle una identificación (a la navegación de nivel inferior circundante) para que pueda provocar el colapso en el menú de acordeón.

Lo que intento generar es algo como esto:

<a href="#collapse2">Titel 2</a>
<ul id="collapse2">Lower Level Menu 2</ul>
<a href="#collapse3">Titel 3</a>
<ul id="collapse3">Lower Level Menu  3</ul>

Mi código para la función start_lvl:

// add id's and classes to ul sub-menus
function start_lvl( &$output, $depth, $item ) {
    // depth dependent classes
    $indent = ( $depth > 0  ? str_repeat( "\t", $depth ) : '' ); // code indent
    $display_depth = ( $depth + 1); // because it counts the first submenu as 0
    $pgid = ; // How to get ID in here??
    $classes = array(
        'sub-menu',
        ( $display_depth == 1  ? 'accordion-body collapse' : '' ),
        ( $display_depth % 2  ? 'menu-odd' : 'menu-even' ),
        ( $display_depth >=2 ? 'sub-sub-menu' : '' ),
        'menu-depth-' . $display_depth
        );
    $ids = array(
        'collapse' . $pgid
        );
    $class_names = implode( ' ', $classes );
    $id_name = implode( ' ', $ids );

    // build html
    $output .= "\n" . $indent . '<ul id="' . $id_name . '" class="' . $class_names . '">' . "\n";
}
Robert Bouten
fuente

Respuestas:

37

Solo tenía que hacer esto en uno de mis temas ... Dado que no tiene acceso a la variable $ item en esa etapa del Walker, desearía almacenar su artículo actual en un ámbito más global en el momento en que tener acceso a ella El siguiente código tendrá más sentido ... nota: he eliminado todo menos el código relevante.

class ThemeTruck_Nav_Walker extends Walker_Nav_Menu {
   private $curItem;

  // retrieve the curItem
  function start_lvl(&$output, $depth = 0, $args = array()) {
    var_dump($this->curItem );
  }

  // store the curItem
  function start_el(&$output, $item, $depth = 0, $args = array(), $id = 0) {
    $this->curItem = $item;
  }

 }
carril
fuente
3
Esta es la solución más elegante presentada en este hilo. Gracias Lane!
Kevin C.
1
De hecho, un enfoque muy limpio que funciona bien. Muchas gracias.
Isaac Gregson
1
No estoy seguro, pero ¿debo agregar todo el código predeterminado a start_el para que funcione?
GDY
44
Ok, puedes usar parent :: start_el ($ output, $ item, $ depth, $ args, $ id); en el start_el ...
GDY
Brillante, tenía la intención de resolver esto por siglos y esto funcionó de inmediato. Gracias.
cfx
3

Tuve un problema similar y lo resolví usando una variable estática dentro de la clase:

static protected $menu_lvl; 

Y luego en el "display_element" incrementé la variable:

self::$menu_lvl++;

En mi código, hice referencia en la función start_lvl algo como esto:

$output .= "<ul id='level". self::$menu_lvl ."'>";

Esto no usa la ID de la página, pero sí usa una ID única para las declaraciones de UL a las que el javascript puede hacer referencia.

Por cierto, esto es realmente útil para acordeones anidados o desplegables anidados en el tema Roots usando Bootstrap para aplicaciones móviles.

Sean Donovan
fuente
2

Puede usar el siguiente filtro en su start_elfunción y arrancar su argumento en start_lvlfunción.

apply_filters( 'walker_nav_menu_start_lvl', $item_output, $item, $depth, $args->myarg=$item->title );

Por favor, avíseme si funciona.

Nabajit Roy
fuente
¡Gracias por publicar! Espero encontrar algo de tiempo para resolverlo en los próximos días, pero estoy muy ocupado con mi estudio en este momento. ¡Me pondré en contacto con usted con el resultado!
Robert Bouten
0

Simplemente puede agregar $ page al argumento del caminante personalizado:

class My_Custom_Walker extends Walker_page {
    function start_el(&$output, $page, $depth, $args, $current_page) {
        if ( $depth )
            $indent = str_repeat("\t", $depth);
        else
            $indent = '';

        extract($args, EXTR_SKIP);

        $output .= $indent . 
            '<li>
            <a style="color:red" href="' . get_page_link($page->ID) . '" title="' . 
            esc_attr( wp_strip_all_tags( apply_filters( 'the_title', $page->post_title, $page->ID ) ) ) . '">' . 
            $link_before . apply_filters( 'the_title', $page->post_title, $page->ID ) . $link_after . '</a>';

Pruebe lo anterior y luego, antes de llamar a wp_list_pages (), agregue la clase de walker personalizada:

$MyWalker = new My_Custom_Walker();

Luego, en los argumentos para wp_list_pages:

wp_list_pages ('walker' => $ MyWalker)

Verifique y vea si la salida del andador es roja.

AlxVallejo
fuente
Eso está en la función start_el, pero aparentemente es diferente en start_lvl porque no puedo poner las mismas variables allí. O al menos no el mismo orden.
Robert Bouten
¿Qué intentas hacer con start_lvl?
AlxVallejo
Estoy tratando de dar a <ul> un id = "collapse102" con 102 la ID de página generada. De esta manera puedo activarlo para colapsarlo en mi menú de acordeón.
Robert Bouten
Agregar el id = "collapse" funciona, pero no puedo hacer que funcione para agregar el pageID también.
Robert Bouten
¿Quieres decir que solo quieres contraer ID específicos? Tengo un árbol de acordeón para wp_list_pages y no necesito modificar start_lvl en absoluto.
AlxVallejo