Custom Walker: jak uzyskać identyfikator w funkcji start_lvl

15

Robię swój pierwszy niestandardowy walker, aby zbudować menu akordeonu. Na początek skorzystałem z tego przykładu: http://bitacre.com/2025/custom-nav-menu-walker-for-wordpress-themes

Istnieją dwie funkcje. Najpierw start_lvl, a następnie start_el.

W start_el identyfikator get jest implementowany przez $ item-> ID. Czy ktoś wie, jak mogę to zrobić również w start_lvl? Muszę nadać (otaczającej nawigacji niższego poziomu) identyfikator, aby można go było zwinąć w menu akordeonu.

Próbuję wygenerować coś takiego:

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

Mój kod dla funkcji 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
źródło

Odpowiedzi:

38

Po prostu musiałem to zrobić w jednym z moich motywów ... Ponieważ nie masz dostępu do zmiennej $ item na tym etapie Walkera, w tej chwili chciałbyś przechowywać swój obecny przedmiot w bardziej globalnym zakresie mieć do niego dostęp. Poniższy kod będzie bardziej sensowny ... uwaga: usunąłem wszystko oprócz odpowiedniego kodu.

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

 }
Pas ruchu
źródło
3
To najbardziej eleganckie rozwiązanie przedstawione w tym wątku. Dzięki Lane!
Kevin C.
1
Rzeczywiście bardzo czyste podejście, które działa dobrze. Wielkie dzięki.
Isaac Gregson
1
Nie jestem pewien, ale czy muszę dodać cały domyślny kod do start_el, aby działał?
GDY
4
Ok, możesz po prostu użyć parent :: start_el ($ output, $ item, $ depth, $ args, $ id); w start_el ...
GDY
Genialne, chciałem to rozgryźć od wieków i to zadziałało od razu. Dziękuję Ci.
porównaj
3

Miałem podobny problem i rozwiązałem go za pomocą zmiennej statycznej wewnątrz klasy:

static protected $menu_lvl; 

A potem w „display_element” zwiększyłem zmienną:

self::$menu_lvl++;

W moim kodzie odwołałem się następnie do funkcji start_lvl mniej więcej tak:

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

To nie używa identyfikatora strony, ale używa unikalnego identyfikatora dla instrukcji UL, do których można odwoływać się w javascript.

BTW - Jest to naprawdę przydatne w przypadku zagnieżdżonych akordeonów lub klikalnych rozwijanych menu rozwijanych w motywie Roots za pomocą Bootstrap do aplikacji mobilnych.

Sean Donovan
źródło
2

Możesz użyć następującego filtra w swojej start_elfunkcji i pogrubić swój argument w start_lvlfunkcji.

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

Daj mi znać, czy to działa.

Nabajit Roy
źródło
Dzięki za opublikowanie! Mam nadzieję, że znajdę trochę czasu, żeby to wypracować w ciągu najbliższych kilku dni, ale teraz jestem bardzo zajęty studiami. Wrócę z wynikiem!
Robert Bouten,
0

Możesz po prostu dodać $ page do argumentu niestandardowego walkera:

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

Wypróbuj powyższe, a następnie przed wywołaniem wp_list_pages () dodaj niestandardową klasę walkera:

$MyWalker = new My_Custom_Walker();

Następnie w argumentach dla stron wp_list_pages:

wp_list_pages ('walker' => $ MyWalker)

Sprawdź i sprawdź, czy wyjście Walkera jest czerwone.

AlxVallejo
źródło
To jest funkcja start_el, ale widocznie jest inna w start_lvl, ponieważ nie mogę tam umieścić tych samych zmiennych. A przynajmniej nie ta sama kolejność.
Robert Bouten,
Co próbujesz zrobić ze start_lvl?
AlxVallejo
Próbuję nadać <ul> id = "collapse102" z 102 wygenerowanym identyfikatorem strony. W ten sposób mogę uruchomić go, aby zwinął go w menu mojego akordeonu.
Robert Bouten,
Dodanie id = "collapse" działa, ale nie mogę zmusić go do dodania identyfikatora strony.
Robert Bouten,
Czy masz na myśli, że chcesz zwinąć tylko określone identyfikatory? Mam drzewo akordeonu dla wp_list_pages i wcale nie muszę zmieniać start_lvl.
AlxVallejo