Добавление контейнера к подменю nav_menu

3 янв. 2013 г., 17:44:22
Просмотры: 28.9K
Голосов: 10

Есть ли способ обернуть div вокруг ul.sub-menu в wp_nav_menu?

Например, чтобы разметка изменилась с такой:

<ul class="menu">

    <li><a href="/">Пункт 1</a></li>
    <li>
        <a href="/">Пункт 2</a>

        <ul class="sub-menu">

            <li><a href="/">Пункт 1</a></li>
            <li><a href="/">Пункт 1</a></li>

        </ul>
   </li>
    <li><a href="/">Пункт 1</a></li>
    <li><a href="/">Пункт 1</a></li>

</ul>

на такую:

<ul class="menu">

    <li><a href="/">Пункт 1</a></li>
    <li>
        <a href="/">Пункт 2</a>

        <div class="sub-menu-wrap">

            <ul class="sub-menu">

                <li><a href="/">Пункт 1</a></li>
                <li><a href="/">Пункт 1</a></li>

            </ul>

        </div>

   </li>

    <li><a href="/">Пункт 1</a></li>
    <li><a href="/">Пункт 1</a></li>

</ul>

Где "sub-menu-wrap" - это пользовательский div.

Это возможно?

0
Все ответы на вопрос 2
6
23

Используйте собственный Walker, расширьте методы start_lvl() и end_lvl().

Пример кода (не тестировался):

class WPSE_78121_Sublevel_Walker extends Walker_Nav_Menu
{
    function start_lvl( &$output, $depth = 0, $args = array() ) {
        $indent = str_repeat("\t", $depth);
        $output .= "\n$indent<div class='sub-menu-wrap'><ul class='sub-menu'>\n";
    }
    function end_lvl( &$output, $depth = 0, $args = array() ) {
        $indent = str_repeat("\t", $depth);
        $output .= "$indent</ul></div>\n";
    }
}

Использование в вашей теме:

wp_nav_menu(
    array (
        'theme_location' => 'your-theme-location-EDIT-THIS',
        'walker'         => new WPSE_78121_Sublevel_Walker
    )
);
3 янв. 2013 г. 17:57:59
Комментарии

Можно ли вносить изменения для каждого элемента меню отдельно? Например, доступен ли класс элемента меню внутри Walker_Nav_Menu и его дочерних элементов?

Dan. Dan.
8 мая 2017 г. 19:08:10

@Dan. Да, это возможно.

fuxia fuxia
8 мая 2017 г. 19:08:40

@fuxia, остается ли этот подход актуальным для WP 5+ или вы рекомендуете альтернативный метод для достижения того же результата?

klewis klewis
9 янв. 2019 г. 16:29:26

@klewis Это всё ещё должно работать.

fuxia fuxia
9 янв. 2019 г. 16:30:15

Как сделать это только на первом уровне.

jho1086 jho1086
31 окт. 2019 г. 10:04:24

@jho1086 - проверьте значение $depth - значение 0 соответствует первому уровню.

Alexander Holsgrove Alexander Holsgrove
6 февр. 2020 г. 13:49:51
Показать остальные 1 комментариев
0

Предлагаемое решение не совсем корректно работает с WordPress - игнорируются стандартные фильтры и код WordPress. Я предлагаю более элегантное решение, которое сохраняет работу всех фильтров, таких как 'nav_menu_submenu_css_class', и другого стандартного кода WordPress:

<?php
/**
 * Оборачивает подменю в div-элемент
 */
class My_Menu_Walker extends Walker_Nav_Menu {

    public function start_lvl( &$output, $depth = 0, $args = null ) {
        $output .=
        '<div class="wrapper">';
        parent::start_lvl($output, $depth, $args);
    }

    public function end_lvl( &$output, $depth = 0, $args = null ) {
        parent::end_lvl($output, $depth, $args);
        $output .= '</div>';
    }

}
11 янв. 2022 г. 00:20:38