Walker Personalizat: cum să obții ID în funcția start_lvl

16 aug. 2012, 22:57:02
Vizualizări: 18.1K
Voturi: 21

Î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";
}
0
Toate răspunsurile la întrebare 3
7
52

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

 }
3 ian. 2013 07:34:27
Comentarii

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

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

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

Isaac Gregson Isaac Gregson
1 iun. 2015 20:08:13

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

GDY GDY
7 feb. 2017 09:27:55

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

GDY GDY
7 feb. 2017 09:37:40

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

cfx cfx
21 iun. 2018 04:55:47

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

Jankyz Jankyz
17 ian. 2020 16:35:38

La ani de zile, asta m-a salvat! Mulțumesc :)

Paxjah Paxjah
5 feb. 2024 21:00:33
Arată celelalte 2 comentarii
2

Puteți utiliza următorul filtru în funcția start_el și preluați argumentul în funcția start_lvl.

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

Vă rog să-mi spuneți dacă funcționează.

16 sept. 2012 12:43:17
Comentarii

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!

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

Nu sunt sigur dacă acest filtru a existat vreodată, dar în WP 5.5 nu văd un astfel de filtru

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

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.

16 aug. 2012 23:29:00
Comentarii

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.

Robert Bouten Robert Bouten
16 aug. 2012 23:38:57

Ce încerci să faci cu start_lvl?

AlxVallejo AlxVallejo
16 aug. 2012 23:40:45

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

Robert Bouten Robert Bouten
16 aug. 2012 23:50:50

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

Robert Bouten Robert Bouten
16 aug. 2012 23:51:58

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.

AlxVallejo AlxVallejo
16 aug. 2012 23:54:56

Am adăugat un exemplu al ceea ce încerc să generez

Robert Bouten Robert Bouten
16 aug. 2012 23:59:43

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

Robert Bouten Robert Bouten
17 aug. 2012 00:00:45

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?

Robert Bouten Robert Bouten
20 aug. 2012 18:14:06

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

AlxVallejo AlxVallejo
20 aug. 2012 18:59:22

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

AlxVallejo AlxVallejo
20 aug. 2012 19:42:23

Mersi Alx, voi începe să lucrez la asta și revin cu întrebări dacă mai am.

Robert Bouten Robert Bouten
21 aug. 2012 23:34:28
Arată celelalte 6 comentarii