Custom Walker: cómo obtener el ID en la función start_lvl
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";
}

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;
}
}

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

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

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

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

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

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

¡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!

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.

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.

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.

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

¿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.

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

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?

@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.

@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.
