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

16 ago 2012, 22:57:02
Vistas: 18.1K
Votos: 21

Estoy creando mi primer Custom Walker para construir un menú acordeón. Para empezar, usé 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 también en start_lvl? Necesito darle al UL (que envuelve la navegación de nivel inferior) un ID para poder activar su colapso en el menú acordeón.

Lo que estoy intentando generar es algo como esto:

<a href="#collapse2">Título 2</a>
<ul id="collapse2">Menú de nivel inferior 2</ul>
<a href="#collapse3">Título 3</a>
<ul id="collapse3">Menú de nivel inferior 3</ul>

Mi código para la función start_lvl:

// añadir ids y clases a los ul de sub-menús
function start_lvl( &$output, $depth, $item ) {
    // clases dependientes de la profundidad
    $indent = ( $depth > 0  ? str_repeat( "\t", $depth ) : '' ); // indentación del código
    $display_depth = ( $depth + 1); // porque cuenta el primer submenú como 0
    $pgid = ; // ¿Cómo obtener el ID aquí??
    $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 );

    // construir html
    $output .= "\n" . $indent . '<ul id="' . $id_name . '" class="' . $class_names . '">' . "\n";
}
0
Todas las respuestas a la pregunta 3
7
52

Acabo de tener que hacer esto en uno de mis temas... Como no tienes acceso a la variable $item en esa etapa del Walker, deberías almacenar tu elemento actual en un ámbito más global en el momento en que sí tienes acceso a él. El siguiente código tendrá más sentido... nota: He eliminado todo excepto el código relevante.

class ThemeTruck_Nav_Walker extends Walker_Nav_Menu {
   private $curItem;

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

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

 }
3 ene 2013 07:34:27
Comentarios

Esta es la solución más elegante presentada en este hilo. ¡Gracias Lane!

Kevin C. Kevin C.
1 jun 2013 01:05:44

Realmente un enfoque muy limpio que funciona bien. Muchas gracias.

Isaac Gregson Isaac Gregson
1 jun 2015 20:08:13

No estoy seguro, pero ¿tengo que agregar todo el código predeterminado a start_el para que funcione?

GDY GDY
7 feb 2017 09:27:55

Puedes usar simplemente parent::start_el($output,$item,$depth,$args,$id); en el start_el ...

GDY GDY
7 feb 2017 09:37:40

¡Brillante! Hace tiempo que quería resolver esto y funcionó de inmediato. Gracias.

cfx cfx
21 jun 2018 04:55:47

¡Genial! Tengo que construir un menú muy grande y tu solución es como ¡bum! Muchas gracias.

Jankyz Jankyz
17 ene 2020 16:35:38

¡Años después esto me ha salvado! Gracias :)

Paxjah Paxjah
5 feb 2024 21:00:33
Mostrar los 2 comentarios restantes
2

Puedes usar el siguiente filtro en tu función start_el y obtener tu argumento en la función start_lvl.

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

Por favor, avísame si funciona.

16 sept 2012 12:43:17
Comentarios

¡Gracias por publicar! Espero encontrar algo de tiempo para resolverlo en los próximos días, pero ahora mismo estoy muy ocupado con mis estudios. ¡Te haré llegar el resultado!

Robert Bouten Robert Bouten
17 sept 2012 23:09:14

No estoy seguro si este filtro existía antes, pero no veo ningún filtro así en WP 5.5

Alexander Holsgrove Alexander Holsgrove
28 oct 2020 21:11:13
11
-1

Puedes simplemente agregar $page como argumento al walker 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>';

Prueba el código anterior y luego, antes de llamar a wp_list_pages(), agrega la clase del walker personalizado:

$MyWalker = new My_Custom_Walker();

Luego, en los argumentos para wp_list_pages:

wp_list_pages('walker' => $MyWalker)

Verifica si la salida del walker aparece en color rojo.

16 ago 2012 23:29:00
Comentarios

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 en el mismo orden.

Robert Bouten Robert Bouten
16 ago 2012 23:38:57

¿Qué estás intentando hacer con start_lvl?

AlxVallejo AlxVallejo
16 ago 2012 23:40:45

Estoy intentando darle al <ul> un id="collapse102" donde 102 es el ID de página generado. De esta manera puedo activarlo para colapsarlo en mi menú acordeón.

Robert Bouten Robert Bouten
16 ago 2012 23:50:50

Agregar el id="collapse" funciona, pero no puedo hacer que también agregue el pageID.

Robert Bouten Robert Bouten
16 ago 2012 23:51:58

¿Te refieres a que solo quieres que colapsen IDs específicos? Tengo un árbol de acordeón para wp_list_pages y no necesito modificar start_lvl en absoluto.

AlxVallejo AlxVallejo
16 ago 2012 23:54:56

He agregado un ejemplo de lo que estoy intentando generar

Robert Bouten Robert Bouten
16 ago 2012 23:59:43

Es para wp_nav_menu, no sé si eso hace alguna diferencia con wp_list_pages

Robert Bouten Robert Bouten
17 ago 2012 00:00:45

Hola AlxVallejo, no logro que funcione como pensé que podría, así que tengo que cambiar mi enfoque. ¿Cómo hiciste tu acordeón para wp_list_pages?

Robert Bouten Robert Bouten
20 ago 2012 18:14:06

@RobertBouten Actualicé mi respuesta. En realidad estoy usando un plugin llamado list-pages-shortcode para no tener que llamar a la clase en cada plantilla de página. Déjame saber cómo te va.

AlxVallejo AlxVallejo
20 ago 2012 18:59:22

@RobertBouten Entiendo que esto no te lleva al 100% del acordeón, lo cual dependerá del jQuery que uses. Lo más probable es que necesites darle a cada enlace una clase para ser llamada desde el DOM de jQuery. Con gusto te explico cómo lo hice.

AlxVallejo AlxVallejo
20 ago 2012 19:42:23

Gracias Alx, empezaré a trabajar en ello y te contactaré si tengo más preguntas.

Robert Bouten Robert Bouten
21 ago 2012 23:34:28
Mostrar los 6 comentarios restantes