Как изменить разметку выпадающего списка навигатора?

Вопрос или проблема

Я использую этот Bootstrap 4 Navwalker, bs4navwalker, чтобы пройтись по пунктам меню WordPress и сгенерировать навигационную панель, как…

Одноуровневый – работает

    <?php
    wp_nav_menu([
      'menu'            => 'primary',
      'theme_location'  => 'primary',
      'container'       => 'nav',
      'container_class' => 'sidebar-nav',
      'menu_id'         => 'sidebarnav',
      'depth'           => 2,
      'fallback_cb'     => 'bs4navwalker::fallback',
      'walker'          => new bs4navwalker()
    ]);
    ?>

Это корректно генерирует навигационную панель, как …

введите описание изображения здесь

<nav class="sidebar-nav">
    <ul id="sidebarnav" class="menu">
        <li id="menu-item-3" class="menu-item menu-item-type-custom menu-item-object-custom current-menu-item current_page_item menu-item-home menu-item-3 nav-item active">
            <a title="Главная страница" target="_blank" href="http://sandbox.contexthq.com/" class="nav-link active" aria-expanded="false">
                <i class="icon-speedometer"></i>Главная страница
            </a>
        </li>
        <li id="menu-item-4" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-4 nav-item">
            <a title="Пример страницы" target="_blank" href="http://example.com/" class="nav-link" aria-expanded="false">
                <i class="ti-layout-grid2"></i>Пример страницы
            </a>
        </li>
        <li id="menu-item-5" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-5 nav-item">
            <a title="Пользовательская страница" target="_blank" href="http://example.com/custom/" class="nav-link" aria-expanded="false">
                <i class="ti-palette"></i>Пользовательская страница
            </a>
        </li>
    </ul>
</nav>

Многоуровневый – предпочтительно

Проблема возникает, когда дело доходит до выпадающих/подменю…

Моя тема обрабатывает их так…

введите описание изображения здесь

<nav class="sidebar-nav">
  <ul id="sidebarnav">
      <li class="selected">
            <a class="has-arrow waves-effect waves-dark" href="https://wordpress.stackexchange.com/questions/308924/javascript:void(0)" aria-expanded="false">
                <i class="icon-speedometer"></i>
                <span class="hide-menu">
                    Панель управления <span class="badge badge-pill badge-cyan">4</span>
                </span>
            </a>
            <ul aria-expanded="false" class="collapse">
              <li><a href="index.html">Минимальная</a></li>
              <li><a href="index2.html">Аналитическая</a></li>
              <li><a href="index3.html">Демографическая</a></li>
              <li class="active"><a href="index4.html" class="active">Современная</a></li>
              <li><a href="index5.html">Криптовалюта</a></li>
          </ul>
      </li>
      <li>
          <a class="has-arrow waves-effect waves-dark" href="https://wordpress.stackexchange.com/questions/308924/javascript:void(0)" aria-expanded="false">
                <i class="ti-layout-grid2"></i>
                <span class="hide-menu">Приложения</span>
          </a>
          <ul aria-expanded="false" class="collapse">
              <li><a href="app-calendar.html">Календарь</a></li>
              <li><a href="app-chat.html">Чат</a></li>
              <li><a href="app-ticket.html">Тикет поддержки</a></li>
              <li><a href="app-contact.html">Контакт / Сотрудник</a></li>
              <li><a href="app-contact2.html">Контактная сетка</a></li>
              <li><a href="app-contact-detail.html">Детали контакта</a></li>
              <li><a href="https://wordpress.stackexchange.com/questions/308924/javascript:void(0)" class="has-arrow">Входящие</a>
                  <ul aria-expanded="false" class="collapse">
                      <li><a href="app-email.html">Почтовый ящик</a></li>
                      <li><a href="app-email-detail.html">Детали почтового ящика</a></li>
                      <li><a href="app-compose.html">Написать письмо</a></li>
                  </ul>
              </li>
          </ul>
      </li>
    </nav>

… То есть это:

  • добавляет <span> с .hide-menu внутрь верхнего уровня ссылки <a>
  • добавляет <ul> неупорядоченный список после.

Это тот подход, которому я хочу следовать.

Многоуровневый: что дает navwalker

Однако, при использовании navwalker, я получаю…

введите описание изображения здесь

<nav class="sidebar-nav">
    <ul id="sidebarnav" class="menu">
        <li id="menu-item-3" class="menu-item menu-item-type-custom menu-item-object-custom current-menu-item current_page_item menu-item-home menu-item-has-children menu-item-3 nav-item dropdown active">
            <a title="Главная страница" target="_blank" href="http://sandbox.contexthq.com/" class="nav-link dropdown-toggle active" data-toggle="dropdown" aria-expanded="false">
                <i class="icon-speedometer"></i>Главная страница</a>
                <div class="dropdown-menu">
                    <a href="http://sandbox.contexthq.com/sample-page/" class="dropdown-item" aria-expanded="false"><i class="ti-palette"></i>Пример страницы</a>
                </div>
        </li>
        ...
    </ul>
</nav>

То есть это…

  • размещает <div> с .dropdown-menu внутри <a>, вместо <span> с .hide-menu
  • для подменю использует элементы <a>

Я уверен, что это стандартное поведение Bootstrap 4 – на самом деле, я с удовольствием использовал это так на другом сайте. Однако, это не то, что требуется от темы Bootstrap 4, которую я купил и в настоящее время пытаюсь превратить в тему WordPress…

Вопрос

Как я могу использовать bs4navwalker, чтобы представить выпадающие/подменю таким образом, чтобы это соответствовало моей теме… ?

ШАГ 1 добавьте скрипт в заголовок, как ниже (всегда лучше использовать метод подключения). Мне нужно, чтобы кто-то помог мне правильно добавить следующий скрипт в WordPress. jQuery должен выполняться перед вторым скриптом>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script>
$(document).ready(function () {
$('.dropdown-menu a.dropdown-toggle').on('click', function(e) {
  if (!$(this).next().hasClass('show')) {
    $(this).parents('.dropdown-menu').first().find('.show').removeClass("show");
  }
  var $subMenu = $(this).next(".dropdown-menu");
  $subMenu.toggleClass('show');


  $(this).parents('li.nav-item.dropdown.show').on('hidden.bs.dropdown', function(e) {
    $('.dropdown-submenu .show').removeClass("show");
  });


  return false;
});
});

</script>

ШАГ 2 Добавьте CSS, как ниже:

.dropdown-submenu {
  position: relative;
}

.dropdown-submenu a::after {
  transform: rotate(-90deg);
  position: absolute;
  right: 6px;
  top: .8em;
}

.dropdown-submenu .dropdown-menu {
  top: 0;
  left: 100%;
  margin-left: .1rem;
  margin-right: .1rem;
}

ШАГ 3 Теперь перейдите в класс walker: найдите && 0 === $depth и удалите его. Также убедитесь, что

'depth' => 3

Теперь он должен начать отображать меню 3-го уровня. Может потребоваться дополнительный CSS. Просто дайте мне знать, как это проходит.

Ответ или решение

Чтобы изменить разметку выпадающего меню в Bootstrap 4 Navwalker (bs4navwalker) в вашем проекте на WordPress, следуйте приведенным ниже шагам. Я опишу процесс, включая изменения в коде и стилизацию, чтобы соответствовать вашим требованиям.

Шаг 1: Изменение класса Walker

Вам нужно внести изменения в файл класса bs4navwalker.php. Откройте этот файл и найдите условие, которое отвечает за глубину меню. Вам нужно удалить проверку на 0 === $depth, чтобы ваше меню могло отображать третьи уровни, а также убедитесь, что вы указали глубину меню не менее 3.

// Найдите строку с условием
if (0 === $depth) {
    // Удалите или измените его
}

Также убедитесь, что в вызове wp_nav_menu в вашем шаблоне указано:

'depth' => 3, // Увеличьте значение глубины

Шаг 2: Изменение разметки

В классе Walker вам нужно настроить вывод HTML для элементов выпадающего меню. Знаковый элемент это то, как выстроена структура. На примере вашего стиля, замените стандартный вывод на разметку с <span> для верхнего уровня и соответствующие <ul> для подменю.

class bs4navwalker extends Walker_Nav_Menu {
    // Переопределите функцию start_el
    function start_el(&$output, $item, $depth = 0, $args = [], $id = 0) {
        // Ваши переменные
        $indent = ($depth) ? str_repeat("\t", $depth) : '';
        $classes = empty($item->classes) ? [] : (array) $item->classes;
        $classes[] = 'nav-item';

        // Убедитесь, что элементы с подменю имеют nav-item dropdown
        if (in_array('menu-item-has-children', $classes)) {
            $classes[] = 'dropdown';
        }

        $class_names = join(' ', apply_filters('nav_item_css_class', array_filter($classes)));
        $class_names = $class_names ? ' class="' . esc_attr($class_names) . '"' : '';

        // Разметка элемента
        $output .= $indent . '<li' . $class_names . '>';

        // Обработайте ссылку
        $atts = [
            'title' => ! empty($item->attr_title) ? $item->attr_title : '',
            'target' => ! empty($item->target) ? $item->target : '',
            'rel' => ! empty($item->xfn) ? $item->xfn : '',
            'href' => ! empty($item->url) ? $item->url : ''
        ];

        $atts = apply_filters('nav_menu_link_attributes', $atts, $item, $args);
        $attributes = '';
        foreach ($atts as $attr => $value) {
            if (! empty($value)) {
                $value = ($attr === 'href') ? esc_url($value) : esc_attr($value);
                $attributes .= ' ' . $attr . '="' . $value . '"';
            }
        }

        // Здесь измените разметку
        if ($depth === 0) {
            $output .= '<a' . $attributes . ' class="nav-link dropdown-toggle" data-toggle="dropdown" aria-expanded="false">';
        } else {
            $output .= '<a' . $attributes . ' class="dropdown-item">';
        }

        $output .= '<i class="' . esc_attr($item->classes[0]) . '"></i>' . esc_html($item->title);
        $output .= '</a>';

        // Подменю
        if ($args->has_children && $depth === 0) {
            $output .= '<ul class="collapse dropdown-menu">';
        }
    }

    // Переопределите функцию end_el при необходимости
}

Шаг 3: Добавление JavaScript и CSS

Добавьте скрипты и стили для функциональности меню. В вашем файле functions.php для WordPress используйте следующий код:

function custom_enqueue_scripts() {
    // Подключение JQuery
    wp_enqueue_script('jquery');
    // Ваш скрипт
    wp_enqueue_script('custom-js', get_template_directory_uri() . '/js/custom.js', array('jquery'), null, true);
}

add_action('wp_enqueue_scripts', 'custom_enqueue_scripts');

Сохраните код JavaScript в custom.js:

jQuery(document).ready(function($) {
    $('.dropdown-menu a.dropdown-toggle').on('click', function(e) {
        if (!$(this).next().hasClass('show')) {
            $(this).parents('.dropdown-menu').first().find('.show').removeClass("show");
        }
        var $subMenu = $(this).next(".dropdown-menu");
        $subMenu.toggleClass('show');

        $(this).parents('li.nav-item.dropdown.show').on('hidden.bs.dropdown', function(e) {
            $('.dropdown-submenu .show').removeClass("show");
        });

        return false;
    });
});

Добавьте CSS стили в ваш файл стилей:

.dropdown-submenu {
    position: relative;
}

.dropdown-submenu a::after {
    transform: rotate(-90deg);
    position: absolute;
    right: 6px;
    top: .8em;
}

.dropdown-submenu .dropdown-menu {
    top: 0;
    left: 100%;
    margin-left: .1rem;
    margin-right: .1rem;
}

Заключение

Следуя этим шагам, вы сможете создать многоуровневое выпадающее меню, которое соответствует дизайну вашей темы. Убедитесь, что вы тестируете каждое изменение, чтобы избежать сбоев в навигации.

Если у вас возникнут дополнительные вопросы или трудности, не стесняйтесь спрашивать. Удачи в реализации ваших целей!

Оцените материал
Добавить комментарий

Капча загружается...