Walker Personalizat: cum să obții ID în funcția start_lvl
Îmi fac primul Walker personalizat pentru a construi un meniu acordeon. Pentru început, am folosit acest exemplu: http://bitacre.com/2025/custom-nav-menu-walker-for-wordpress-themes
Există două funcții. Prima este start_lvl și apoi start_el.
În start_el, ID-ul este implementat prin $item->ID. Știe cineva cum pot face acest lucru și în start_lvl? Am nevoie să dau un ID pentru <ul> (care înconjoară navigația de nivel inferior) pentru a-l putea declanșa să se închidă în meniul acordeon.
Ceea ce încerc să generez este ceva de genul:
<a href="#collapse2">Titlu 2</a>
<ul id="collapse2">Meniul de nivel inferior 2</ul>
<a href="#collapse3">Titlu 3</a>
<ul id="collapse3">Meniul de nivel inferior 3</ul>
Codul meu pentru funcția start_lvl:
// adaugă ID-uri și clase la <ul> pentru submeniuri
function start_lvl( &$output, $depth, $item ) {
// clase dependente de adâncime
$indent = ( $depth > 0 ? str_repeat( "\t", $depth ) : '' ); // indentare cod
$display_depth = ( $depth + 1); // deoarece consideră primul submeniu ca 0
$pgid = ; // Cum să obțin ID-ul aici??
$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 );
// construiește html
$output .= "\n" . $indent . '<ul id="' . $id_name . '" class="' . $class_names . '">' . "\n";
}

Tocmai a trebuit să fac asta într-unul dintre temele mele... Deoarece nu ai acces la variabila $item în acea etapă a Walker-ului, ai nevoie să stochezi elementul curent într-un domeniu mai global în momentul în care ai acces la el. Următorul cod va avea mai mult sens... notă: am eliminat totul în afară de codul relevant.
class ThemeTruck_Nav_Walker extends Walker_Nav_Menu {
private $curItem;
// preia curItem
function start_lvl(&$output, $depth = 0, $args = array()) {
var_dump($this->curItem );
}
// stochează curItem
function start_el(&$output, $item, $depth = 0, $args = array(), $id = 0) {
$this->curItem = $item;
}
}

Aceasta este cea mai elegantă soluție prezentată în acest thread. Mulțumesc, Lane!

Într-adevăr o abordare foarte curată care funcționează excelent. Multe mulțumiri.

Nu sunt sigur, dar trebuie să adaug întregul cod implicit la start_el ca să funcționeze?

Ok, poți folosi pur și simplu parent::start_el($output,$item,$depth,$args,$id); în start_el ...

Genial, de mult timp voiam să rezolv asta și a funcționat imediat. Mulțumesc.

Super!! Am de construit un meniu foarte mare și soluția ta este gen booom. Mulțumesc!

Mulțumesc pentru postare! Sper să găsesc ceva timp să rezolv problema în următoarele zile, dar momentan sunt foarte ocupat cu studiile. Revin cu rezultatele!

Puteți adăuga pur și simplu $page ca argument pentru walker-ul personalizat:
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>';
Încercați codul de mai sus și apoi, înainte de a apela wp_list_pages(), adăugați clasa walker personalizată:
$MyWalker = new My_Custom_Walker();
Apoi, în argumentele pentru wp_list_pages:
wp_list_pages('walker' => $MyWalker)
Verificați dacă rezultatul walker-ului este roșu.

Aceasta se află în funcția start_el, dar aparent este diferit în start_lvl pentru că nu pot pune aceleași variabile acolo. Sau cel puțin nu în aceeași ordine.

Încerc să dau elementului <ul> un id="collapse102" unde 102 este ID-ul generat al paginii. În acest fel pot declanșa collapsul în meniul meu de acordeon.

Adăugarea id="collapse" funcționează, dar nu reușesc să o fac să funcționeze și pentru a adăuga pageID.

Vrei să spui că dorești ca doar anumite ID-uri să fie restrânse? Am un arbore acordeon pentru wp_list_pages și nu este nevoie să modific start_lvl deloc.

Este pentru wp_nav_menu, nu știu dacă face vreo diferență pentru wp_list_pages

Bună AlxVallejo, nu reușesc să fac să funcționeze așa cum credeam eu, așa că trebuie să schimb abordarea. Cum ai făcut tu acordeonul pentru wp_list_pages?

@RobertBouten Am actualizat răspunsul meu. De fapt, folosesc un plugin numit list-pages-shortcode, astfel încât nu trebuie să apelez clasa pe fiecare șablon de pagină. Spune-mi cum merge.

@RobertBouten Îmi dau seama că asta nu te duce 100% la acordeon, ceea ce va depinde de jQuery pe care îl folosești. Cel mai probabil ai putea să dai fiecărui link o clasă care să fie apelată din DOM-ul jQuery. Aș fi bucuros să te ghidez prin modul în care am făcut eu asta.
