Custom Walker: как получить ID в функции start_lvl

14

Я делаю свой первый пользовательский ходок для создания меню аккордеона. Для начала я использовал этот пример: http://bitacre.com/2025/custom-nav-menu-walker-for-wordpress-themes

Есть две функции. Сначала start_lvl, а затем start_el.

В start_el идентификатор get реализован с помощью $ item-> ID. Кто-нибудь знает, как я могу сделать это в start_lvl? Мне нужно дать (окружающий навигацию более низкого уровня) идентификатор, чтобы я мог вызвать его свертывание в меню аккордеона.

Я пытаюсь создать что-то вроде этого:

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

Мой код для функции 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";
}
Роберт Боутен
источник

Ответы:

37

Мне просто нужно было сделать это в одной из моих тем ... Поскольку у вас нет доступа к переменной $ item на этом этапе Walker, вы захотите сохранить текущий элемент в более глобальном контексте в тот момент, когда вы у меня есть доступ к нему. Следующий код будет иметь больше смысла ... примечание: я удалил все, кроме соответствующего кода.

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

 }
полоса дороги
источник
3
Это самое элегантное решение, представленное в этой теме. Спасибо, Лейн!
Кевин С.
1
Действительно очень чистый подход, который хорошо работает. Большое спасибо.
Исаак Грегсон
1
Я не уверен, но мне нужно добавить весь код по умолчанию для start_el, чтобы он работал?
GDY
4
Хорошо, вы можете просто использовать parent :: start_el ($ output, $ item, $ deep, $ args, $ id); в start_el ...
GDY
Блестящий, хотел выяснить это целую вечность, и это сработало сразу. Спасибо.
cfx
3

У меня была похожая проблема, и я решил ее с помощью статической переменной внутри класса:

static protected $menu_lvl; 

А затем в "display_element" я увеличил переменную:

self::$menu_lvl++;

В моем коде я тогда ссылался в функции start_lvl примерно так:

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

Это не использует идентификатор страницы, но он использует уникальный идентификатор для операторов UL, на который может ссылаться JavaScript.

Кстати, это действительно просто полезно для вложенных аккордеонов или кликабельных вложенных выпадающих меню в теме Roots с использованием Bootstrap для мобильных приложений.

Шон Донован
источник
2

Вы можете использовать следующий фильтр в своей start_elфункции и получить свой аргумент в start_lvlфункции.

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

Пожалуйста, дайте мне знать, если это работает.

Набаджит Рой
источник
Спасибо за публикацию! Я надеюсь найти время, чтобы разобраться с этим в ближайшие несколько дней, но сейчас я действительно занят своей учебой. Я вернусь к вам с результатом!
Роберт Боутен
0

Вы можете просто добавить $ page к аргументу пользовательского обходчика:

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

Попробуйте описанное выше, а затем, прежде чем вызывать wp_list_pages (), добавьте пользовательский класс Walker:

$MyWalker = new My_Custom_Walker();

Затем в аргументах для wp_list_pages:

wp_list_pages ('walker' => $ MyWalker)

Проверьте и убедитесь, что выход ходунка красный.

AlxVallejo
источник
Это есть в функции start_el, но в start_lvl она явно отличается, потому что я не могу поместить туда те же переменные. Или, по крайней мере, не в том же порядке.
Роберт Боутен
Что вы пытаетесь сделать с start_lvl?
AlxVallejo
Я пытаюсь дать <ul> id = "collapse102" со 102 сгенерированным идентификатором страницы. Таким образом, я могу запустить его, чтобы свернуть в моем меню аккордеона.
Роберт Боутен
Добавление id = "collapse" работает, но я не могу заставить его работать и добавить pageID.
Роберт Боутен
Вы хотите сказать, что вы хотите свернуть только определенные идентификаторы? У меня есть дерево аккордеона для wp_list_pages, и мне вообще не нужно изменять start_lvl.
AlxVallejo