pdoMenu и Bootstrap 4

pdoMenu и Bootstrap 4

Есть MODX с pdoMenu, задача - получить вывод меню в соответствии с bootstrap.

Можно найти множество вариантов реализации, но большая часть того что есть - под bootstrap 3, в четвертой версии есть некоторые отличия, потому делал свое.

Получить нужно следующее:

<nav class="navbar navbar-expand-lg navbar-light bg-light">
  <a class="navbar-brand" href="#">Навигация</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Меню">
    <span class="navbar-toggler-icon"></span>
  </button>
  <div class="collapse navbar-collapse" id="navbarNavDropdown">
    <ul class="navbar-nav">
      <li class="nav-item active">
        <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">Features</a>
      </li>
      <li class="nav-item">
        <a class="nav-link" href="#">Pricing</a>
      </li>
      <li class="nav-item dropdown">
        <a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
          Dropdown link
        </a>
        <div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
          <a class="dropdown-item" href="#">Action</a>
          <a class="dropdown-item" href="#">Another action</a>
          <a class="dropdown-item" href="#">Something else here</a>
        </div>
      </li>
    </ul>
  </div>
</nav>

Открытие выпадающего меню по клику

<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">Навигация</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown3" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Меню">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNavDropdown3">
[[pdoMenu?
&parents=`0`
&level=`2`
&outerClass=`navbar-nav`
&tpl=`@INLINE <li[[+classes]]><a href="[[+link]]" [[+attributes]] class="nav-link">[[+menutitle]]</a>[[+wrapper]]</li>`
&rowClass=`nav-item`
&parentClass=`dropdown`
&tplParentRow=`@INLINE <li[[+classes]]><a href="[[+link]]" [[+attributes]] class="nav-link dropdown-toggle" data-toggle="dropdown">[[+menutitle]]</a><ul class="dropdown-menu">[[+wrapper]]</ul></li>`
&tplInner=`@INLINE [[+wrapper]]`
]]
</div>
</nav>

Подойдет в таком виде, если нет ресурсов-контейнеров, документы которых не должны быть видны в меню.

Учитывая, что каждому документу отдельно ставить "не показывать в меню" не вариант (к примеру, новости), выведем разные шаблоны для родительских пунктов в зависимости от id ресурса.

Вместо "id" можно использовать, к примеру, "template", если таких ресурсов много и у них один шаблон.

В @inline проверка работать не будет, а значит нужно создать отдельный чанк "MenuParentRow" с таким содержимым:

<li[[+classes]]><a href="[[+link]]" [[+attributes]] class="nav-link[[+id:ne=`2`:then=` dropdown-toggle" data-toggle="dropdown`]]">[[+menutitle]]</a>[[+id:ne=`2`:then=`<ul class="dropdown-menu">[[+wrapper]]</ul>`]]</li>

И укажем его в вызове pdoMenu

.....
&tplParentRow=`MenuParentRow`
.....

Здесь ресурс с id 2 - тот самый раздел с новостями.

Выпадающее меню по наведению, или клику в зависимости от устройства

Самый простой вариант сделать показ подпунктов без клика - прописать в css:

@media (min-width: 992px) {
.nav-item:hover ul {display:block}
}

А если еще и убрать атрибут data-toggle и заодно класс "dropdown-toggle" у ссылок - они станут кликабельными с переходом на страницу. Остается одна проблема - в мобильной версии нужно раскрытие по нажатию.

Что бы ссылка с компьютера была рабочей, а с мобильного использовалась для раскрытия sub-меню предлагаю использовать небольшой скрипт с проверкой на мобильную версию. Атрибут data-toggle и класс dropdown-toggle при этом убирать не нужно, это сделает скрипт если пользователь зашел с desktop версии:

if( !/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
	$('a.dropdown-toggle').removeAttr('data-toggle').removeAttr('aria-expanded').removeClass('dropdown-toggle');
}

Сказать $пасибо (это совсем не обязательно)

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

Комментарии ()

  1. zank 22 июня 2018, 21:12(Комментарий был изменён)
    0 #

    <button class=«navbar-toggler» type=«button» data-toggle=«collapse» data-target="#navbarNavDropdown3"
    У вас в коде фигурирует navbarNavDropdown3, не пойму почему3? опечатка?

    1. Владимир 22 июня 2018, 22:01
      0 #

      Нет, в атрибуте data-target указывается ID блока с меню, может быть все что угодно, главное что бы совпадало:

      <div class="collapse navbar-collapse" id="navbarNavDropdown3">