Оценок: 1
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
Надежный хостинг VPS серверов
  • Свои ISO образы
  • VDS с оплатой раз и навсегда
  • Аренда VDS на любой срок, с оплатой по дням
  • Большое разнообразие конфигураций
  • Дата-центры в ЕС и России
+ скидка 10%

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

  1. Послезавтра сайт сдавать. Осталось только меню человеческое сделать. Очень помогли. Думал, несколько часов уйдет, чтобы с pdoMenu разобраться, но просто скопировал ваш пример и все отлично работает. Только добавил еще к «navbar-nav» класс «mr-auto», чтобы телефон в этой же строке к левому краю не прилипал. Спасибо.

    ivankrivenko 08 января 2019, 00:34 +1
    • Прошу прощения, забыл вписать html код в

      Показать код
      
      <code> <ul class="navbar-nav">
          <li class="nav-item">
            <a class="nav-link" href="[[~1]]">Меню1</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="[[~2]]">Меню2</a>
          </li>
      </ul>
      

      Vitaliy 29 сентября 2018, 22:50 0
      • Через параметр tpl, как в примере:

        Показать код
        &tpl=`@INLINE <li[[+classes]]><a href="[[+link]]" [[+attributes]] class="nav-link">[[+menutitle]]</a>[[+wrapper]]</li>`
        приведенный код вообще похоже не отсюда… скопируйте пример, посмотрите что выйдет

        Владимир 29 сентября 2018, 14:27 0
        • Меню1
        • Меню2
        Вот что имею:
        [[pdoMenu?
        &parents=`0`
        &level=`1`
        &firstClass=`0`
        &lastClass=`0`
        &outerClass=`navbar-nav`
        &hereClass=`current-menu-item`
        &rowClass=`nav-item`
        ]]
        В итоге не выводится class=«nav-link» в меню, как этот класс прописать в pdoMenu?

        Vitaliy 29 сентября 2018, 22:49 0
        • <button class=«navbar-toggler» type=«button» data-toggle=«collapse» data-target="#navbarNavDropdown3"
          У вас в коде фигурирует navbarNavDropdown3, не пойму почему3? опечатка?

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

            Показать код
            <div class="collapse navbar-collapse" id="navbarNavDropdown3">

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