pdoMenu — документация и примеры создания меню в MODX

pdoMenu - документация и примеры создания меню в MODX MODX Revo
В данном уроке изучим документацию по сниппету pdoMenu, который входит в состав дополнения pdoTools. И научимся создавать меню различной сложности.

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

Создавать динамическое меню в MODX мы будем при помощи сниппета PdoMenu (замена устаревшего Wayfinder) из пакета pdoTools. Перед тем как начать ознакомьтесь с основной документацией.

Документация по pdoMenu

pdoMenu по умолчанию принимает общие параметры pdoTools и некоторые свои.

Параметры

Название По умолчанию Описание
&parents Текущий ресурс Список родителей (категорий) для поиска результатов, указываются через запятую. Если поставить 0 (&parents=`0`) — выборка не ограничивается. Если хотите исключить id родителя (и его потомков) из выборки, укажите его через дефис.
&level 0 (не ограниченно) Уровень генерируемого меню.
&resources Список ресурсов для вывода в результатах, через запятую. Как и в случае с родителями, если id ресурса начинается с дефиса, то ресурс исключается из выборки.
&templates Список шаблонов для фильтрации результатов, через запятую. Если id шаблона начинается с дефиса, ресурсы с ним исключается из выборки.
&where Массив дополнительных параметров выборки, закодированный в JSON.
&displayStart 0 Включить показ начальных узлов меню. Полезно при указании более одного «parents».
&context Ограничение выборки по контексту ресурсов.
&showHidden 0 Показывать ресурсы, скрытые в меню.
&showUnpublished 0 Показывать неопубликованные ресурсы.
&previewUnpublished 0 Включить показ неопубликованных ресурсов, если у пользователя есть на это разрешение.
&hideSubMenus 0 Спрятать неактивные ветки меню.
&select Список полей для выборки, через запятую. Можно указывать JSON-строку с массивом, например &select=`{«modResource»:»id,pagetitle,content»}`
&sortby menuindex Любое поле ресурса для сортировки, включая ТВ-параметр, если он указан в параметре &includeTVs, например &sortby=`{«tvname»:»ASC»,»pagetitle»:»DESC»}`. Можно указывать JSON-строку с массивом нескольких полей. Для случайной сортировки укажите &sortby=`RAND()`
&sortdir ASC Направление сортировки: по убыванию или по возрастанию. Если оставить параметры &sortby и &sortdir пустыми, то сортировка будет идти по порядку ресурсов в &resources.
&limit 0 Ограничение количества результатов выборки.
&offset 0 Пропуск результатов от начала. Необходимо использовать вместе с явно указанным &limit
&checkPermissions Укажите, какие разрешения нужно проверять у пользователя при выводе ресурсов, например &checkPermissions=`list`.
&countChildren 0 Точный подсчет количества дочерних ресурсов каждой категории и вывод их в плейсхолдер [[+children]]. Делает дополнительные запросы в БД, поэтому по умолчанию отключен.
&toPlaceholder Если не пусто, сниппет сохранит все данные в плейсхолдер с этим именем вместо вывода на экран.
&plPrefix wf. Префикс для выставляемых плейсхолдеров.
&showLog 0 Показывать дополнительную информацию о работе сниппета. Только для авторизованных в контексте «mgr».
&fastMode 0 Быстрый режим обработки чанков. Все необработанные теги (условия, сниппеты и т.п.) будут вырезаны.
&cache 0 Кэширование результатов работы сниппета.
&cacheTime 3600 Время актуальности кэша, в секундах.
&scheme -1 Схема формирования url, передаётся в modX::makeUrl(), поэтому возможные варианты нужно смотреть здесь. Особый тип uri подставляет значение uri ресурса, без запуска функции.
&useWeblinkUrl 1 Генерировать ссылку с учетом класса ресурса.
&rowIdPrefix Префикс id=»» для выставления идентификатора в чанк.
&hereId id текущего ресурса для генерируемого меню. Нужно указывать только если скрипт сам его неверно определяет, например при выводе меню из чанка другого сниппета.
&includeTVs Список ТВ-параметров для выборки, через запятую. Например &includeTVs=`action,time` дадут плейсхолдеры [[+action]] и [[+time]].
&prepareTVs Список ТВ-параметров, с файлами из источников медиа, для которых нужно сгенерировать полные пути. Если установить &prepareTVs=`1`, будут подготовлены все ТВ, указанные в &includeTVs.
&processTVs Список ТВ-параметров, которые нужно обработать и вывести согласно их настроек в менеджере системы. Если установить &processTVs=`1`, будут обработаны все ТВ, указанные в &includeTVs. Замедляет работу.
&tvPrefix Префикс для ТВ-параметров.

Параметры шаблонов

Эти параметры устанавливают чанки, которые содержат шаблоны для генерации меню.

Название Описание
&tplOuter Чанк оформления всего блока меню. По умолчанию: @INLINE <ul [[+classes]]>[[+wrapper]]</ul>
&tpl Чанк оформления пункта меню. Если не указан, то содержимое полей ресурса будет распечатано на экран. По умолчанию: @INLINE <li [[+classes]]><a href="[[+link]]" [[+attributes]]>[[+menutitle]]</a>[[+wrapper]]</li>
&tplHere Чанк оформления текущего пункта меню.
&tplStart Чанк оформления корневого пункта, при условии, что включен &displayStart. По умолчанию: @INLINE <h2 [[+classes]]>[[+menutitle]]</h2>[[+wrapper]]
&tplParentRow Чанк оформления родителя с потомками, не подпадающего под условия &tplCategoryFolder. Например: @INLINE <li class="submenu_wrapp [[+classnames]]"><a href="[[+link]]" [[+attributes]]>[[+menutitle]]</a>[[+wrapper]]</li>
&tplParentRowHere Чанк оформления текущего документа, если он содержит потомков.
&tplParentRowActive Чанк оформления родителей с потомками в активной ветке меню.
&tplCategoryFolder Специальный чанк оформления категории. Категорией считается родитель с потомками, у которого указан пустой шаблон или rel="category" в поле link_attributes.
&tplInner Чанк оформления всего блока подпунктов меню. Если пуст — будет использовать &tplOuter. Например: @INLINE <ul class="submenu [[+classnames]]">[[+wrapper]]</ul>
&tplInnerRow Чанк оформления подпункта меню. Например: @INLINE <li class="submenu_item [[+classnames]]"><a href="[[+link]]" [[+attributes]]>[[+menutitle]]</a>[[+wrapper]]</li>
&tplInnerHere Чанк оформления активного подпункта меню.

Параметры CSS классов

Эти параметры задают значение плейсхолдеров [[+classnames]] и [[+classes]] для различных элементов меню. Плейсхолдер [[+classnames]] выводит только название класса без атрибута class="", в отличие от плейсхолдера [[+classes]].

Название Описание
&firstClass Класс для первого пункта меню. По умолчанию: first
&lastClass Класс последнего пункта меню. По умолчанию: last
&hereClass Класс для активного пункта меню. По умолчанию: active
&parentClass Класс категории меню.
&rowClass Класс пункта меню.
&outerClass Класс обертки блока меню.
&innerClass Класс обертки блока подпунктов меню.
&levelClass Класс уровня меню. Например если укажите «level», то будет «level1», «level2» и т.д.
&selfClass Класс текущего ресурса в меню.
&webLinkClass Класс ресурса-ссылки.

Официальные примеры

Обычный вывод меню из корня сайта в один уровень:

[[pdoMenu?
    &parents=`0`
    &level=`1`
]]

Вывод с исключением определенных родителей и проверкой разрешений пользователя:

[[pdoMenu?
    &parents=`-10,-15`
    &level=`2`
    &checkPermissions=`load,list,view`
]]

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

[[pdoMenu?
    &parents=`10,15`
    &displayStart=`1`
]]

Вывод двух уровней ресурсов с подсчетом количества вложенных:

[[pdoMenu?
    &parents=`0`
    &level=`2`
    &tplInner=`@INLINE [[+wrapper]]`
    &tplParentRow=`@INLINE <li [[+classes]]><a href="[[+link]]" [[+attributes]]>[[+menutitle]]</a> ([[+children]])</li>[[+wrapper]]`
    &countChildren=`1`
]]

Официальную документацию можете почитать здесь. А сейчас разберем самые типовые вызовы меню.

Вызов PdoMenu

Вариант 1. На месте этого статического меню вызовем сниппет pdoMenu, для этого в дереве ресурсов, на вкладке “Элементы” в разделе сниппеты разверните ветку pdoTools, далее нажмите на pdoMenu левой кнопкой мыши (не отпускайте кнопку) и перетащите этот сниппет в место, где вы хотите вызвать меню, далее в открывшемся окошке заполните необходимые параметры и нажмите «Сохранить«.

Вызов pdoMenu из снипептов перетаскиванием

Вариант 2. Просто вручную пишем вызов.

Типовые примеры

Обычное одноуровневое меню

К примеру у нас самое обычное меню, со следующей html разметкой (взял меню из подвала / footer).

<ul>
     <li><i class="bi bi-chevron-right"></i> <a href="#">Home</a></li>
     <li><i class="bi bi-chevron-right"></i> <a href="#">About us</a></li>
     <li><i class="bi bi-chevron-right"></i> <a href="#">Services</a></li>
     <li><i class="bi bi-chevron-right"></i> <a href="#">Terms of service</a></li>
     <li><i class="bi bi-chevron-right"></i> <a href="#">Privacy policy</a></li>
</ul>

К примеру нам в него нужно вывести только ресурсы первого уровня, у которых в настройках не стоит галка на против пункта «Скрыть из меню». Тогда вызов получится следующим:

[[pdoMenu?
	&parents=`0`
	&level=`1`
	&firstClass=`0`
	&lastClass=`0`
	&tpl=`@INLINE <li[[+classes]]><i class="bi bi-chevron-right"></i> <a href="[[+link]]" [[+attributes]]>[[+menutitle]]</a>[[+wrapper]]</li>`
]]
fenom

{'pdoMenu' | snippet : [
	'parents' => '0',
	'level' => '1',
	'firstClass' => '0',
	'lastClass' => '0',
	'tpl' => '@INLINE <li{$classes}><i class="bi bi-chevron-right"></i> <a href="{$link}" {$attributes}>{$menutitle}</a>{$wrapper}</li>'
]}

где:

  • &parents=`0` — список родителей (т.е. берем все ресурсы).
  • &lastClass=`0` — класс последнего пункта меню (он как обычно не нужен);
  • &firstClass=`0` — класс для первого пункта меню (он как обычно не нужен);
  • &level=`1` — уровень вложенности (в данном случае 1);
  • &tpl=`@INLINE <li[[+classes]]><i class="bi bi-chevron-right"></i> <a href="[[+link]]" [[+attributes]]>[[+menutitle]]</a>[[+wrapper]]</li>` — чанк оформления пункта меню;

В свежей версии PdoTools заметил особенность, если не указать &parents=`0`, то вообще ничего не выводится.

Теперь давайте разберем как в наше меню вывести определенные ресурсы, не важно скрыты они в меню или нет. Для этого к вызову выше допишите еще 2 параметра:

  • &showHidden=`1` — показываем даже те ресурсы у которых стоит галка в настройках ресурса у пункта не Скрыть из меню;
  • &resources=`1,6,7,8` — список ресурсов (их id), которые нужно вывести в меню;

Усложняем задачу.

Выпадающее меню на MODX

Берем полную разметку нашего верхнего меню:

<nav id="navbar" class="navbar">
        <ul>
          <li><a class="nav-link scrollto active" href="#hero">Home</a></li>
          <li><a class="nav-link scrollto" href="#about">About</a></li>
          <li><a class="nav-link scrollto" href="#services">Services</a></li>
          <li><a class="nav-link scrollto" href="#portfolio">Portfolio</a></li>
          <li><a class="nav-link scrollto" href="#team">Team</a></li>
          <li><a href="blog.html">Blog</a></li>
          <li class="dropdown"><a href="#"><span>Drop Down</span> <i class="bi bi-chevron-down"></i></a>
            <ul>
              <li><a href="#">Drop Down 1</a></li>
              <li class="dropdown"><a href="#"><span>Deep Drop Down</span> <i class="bi bi-chevron-right"></i></a>
                <ul>
                  <li><a href="#">Deep Drop Down 1</a></li>
                  <li><a href="#">Deep Drop Down 2</a></li>
                  <li><a href="#">Deep Drop Down 3</a></li>
                  <li><a href="#">Deep Drop Down 4</a></li>
                  <li><a href="#">Deep Drop Down 5</a></li>
                </ul>
              </li>
              <li><a href="#">Drop Down 2</a></li>
              <li><a href="#">Drop Down 3</a></li>
              <li><a href="#">Drop Down 4</a></li>
            </ul>
          </li>
          <li><a class="nav-link scrollto" href="#contact">Contact</a></li>
          <li><a class="getstarted scrollto" href="#about">Get Started</a></li>
        </ul>
        <i class="bi bi-list mobile-nav-toggle"></i>
      </nav><!-- .navbar -->

Убрал из разметки <li class="dropdown megamenu">...</li>. Здесь у нас больше лендинговое меню, с якорными ссылками, и обычными, которое можно посадить примерно так:

<nav id="navbar" class="navbar">
        <ul>
          <li><a class="nav-link scrollto active" href="[[~1]]#hero">Главная</a></li>
          <li><a class="nav-link scrollto" href="[[~1]]#about">О нас</a></li>
          <li><a class="nav-link scrollto" href="[[~1]]#services">Услуги</a></li>
          <li><a class="nav-link scrollto" href="[[~1]]#portfolio">Портфолио</a></li>
          <li><a class="nav-link scrollto" href="[[~1]]#team">Команда</a></li>
          <li><a href="[[~8]]">Блог</a></li>
          <li class="dropdown"><a href="#"><span>Drop Down</span> <i class="bi bi-chevron-down"></i></a>
            [[!pdoMenu?
                &parents=`3`
            	&lastClass=`0`
            	&firstClass=`0`
            	&level=`3`
            	&tpl=`@INLINE <li><a[[+classes]] href="[[+link]]" [[+attributes]]>[[+menutitle]]</a>[[+wrapper]]</li>`
            	&tplParentRow=`@INLINE <li class="dropdown"><a href="[[+link]]"[[+classes]] [[+attributes]]>[[+menutitle]] <i class="bi bi-chevron-down"></i></a>[[+wrapper]]</li>`
            	&tplInner=`@INLINE <ul[[+classes]]>[[+wrapper]]</ul>`
            ]] 
          </li>
          <li><a class="nav-link scrollto" href="[[~1]]#contact">Контакты</a></li>
          <li><a class="getstarted scrollto" href="[[~1]]#about">Быстрый старт</a></li>
        </ul>
        <i class="bi bi-list mobile-nav-toggle"></i>
      </nav><!-- .navbar -->

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

[[!pdoMenu?
    &parents=`0`
	&lastClass=`0`
	&firstClass=`0`
	&level=`3`
	&tplOuter=`@INLINE <nav id="navbar" class="navbar"><ul>[[+wrapper]]</ul><i class="bi bi-list mobile-nav-toggle"></i></nav>`
	&tpl=`@INLINE <li><a[[+classes]] href="[[+link]]" [[+attributes]]>[[+menutitle]]</a>[[+wrapper]]</li>`
	&tplParentRow=`@INLINE <li class="dropdown"><a href="[[+link]]"[[+classes]] [[+attributes]]>[[+menutitle]] <i class="bi bi-chevron-down"></i></a>[[+wrapper]]</li>`
	&tplInner=`@INLINE <ul[[+classes]]>[[+wrapper]]</ul>`
]]
fenom

{'!pdoMenu' | snippet : [
    'parents' => '0',
	'lastClass' => '0',
	'firstClass' => '0',
	'level' => '3',
	'tplOuter' => '@INLINE <nav id="navbar" class="navbar"><ul>{$wrapper}</ul><i class="bi bi-list mobile-nav-toggle"></i></nav>',
	'tpl' => '@INLINE <li><a{$classes} href="{$link}" {$attributes}>{$menutitle}</a>{$wrapper}</li>',
	'tplParentRow' => '@INLINE <li class="dropdown"><a href="{$link}"{$classes} {$attributes}>{$menutitle} <i class="bi bi-chevron-down"></i></a>{$wrapper}</li>',
	'tplInner' => '@INLINE <ul{$classes}>{$wrapper}</ul>'
]}

Пример 2

Разметка у нас имеет следующий код:

<ul class="nav nav-pills" id="mainNav">
	<li><a href="demo-auto-services.html" class="nav-link active">Home</a></li>
	<li><a href="demo-auto-services-about-us.html" class="nav-link">About</a></li>
	<li class="dropdown">
		<a href="demo-auto-services-services.html" class="nav-link dropdown-toggle">Services</a>
		<ul class="dropdown-menu">
			<li><a href="demo-auto-services-services-detail.html" class="dropdown-item">Brake Repair</a></li>
			<li><a href="demo-auto-services-services-detail.html" class="dropdown-item">Check Engine</a></li>
			<li><a href="demo-auto-services-services-detail.html" class="dropdown-item">Suspension Repair</a></li>
			<li><a href="demo-auto-services-services-detail.html" class="dropdown-item">Transmission Repair</a></li>
			<li><a href="demo-auto-services-services-detail.html" class="dropdown-item">A/C Repair</a></li>
		</ul>
	</li>
	<li><a href="demo-auto-services-products.html" class="nav-link">Products</a></li>
	<li><a href="demo-auto-services-blog.html" class="nav-link">Blog</a></li>
	<li><a href="demo-auto-services-appointment.html" class="nav-link">Appointment</a></li>
	<li><a href="demo-auto-services-contact.html" class="nav-link">Contact</a></li>
</ul>

Вызов получается вот таким:

[[!pdoMenu?
    &parents=`0`
	&lastClass=`0`
	&firstClass=`0`
	&level=`2`
	&outerClass=`nav nav-pills`
	&tplOuter=`@INLINE <ul[[+classes]] id="mainNav">[[+wrapper]]</ul>`
	&rowClass=`nav-link`
	&innerClass=`dropdown-menu`
	&tpl=`@INLINE <li><a[[+classes]] href="[[+link]]" [[+attributes]]>[[+menutitle]]</a>[[+wrapper]]</li>`
	&parentClass=`dropdown-toggle`
	&tplParentRow=`@INLINE <li class="dropdown"><a href="[[+link]]"[[+classes]][[+attributes]]>[[+menutitle]]</a>[[+wrapper]]</li>`
    &innerClass=`dropdown-menu`
	&tplInner=`@INLINE <ul[[+classes]]>[[+wrapper]]</ul>`
]]

По текущему сайту все, но для закрепления результатов приведу еще примеры.

Пример 3: выпадающее меню на bootstrap 5

Возьмём разметку bootstrap 5 со стабильной версии к примеру 5.1: https://getbootstrap.com/docs/5.1/components/navbar/#supported-content

bootstrap 5 меню

Если убрать обвертку с бургером (кнопкой) и окошко поиска, то статический html код выглядит так:

     <ul class="navbar-nav me-auto mb-2 mb-lg-0">
        <li class="nav-item">
          <a class="nav-link active" aria-current="page" href="#">Home</a>
        </li>
        <li class="nav-item">
          <a class="nav-link" href="#">Link</a>
        </li>
        <li class="nav-item dropdown">
          <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false">
            Dropdown
          </a>
          <ul class="dropdown-menu" aria-labelledby="navbarDropdown">
            <li><a class="dropdown-item" href="#">Action</a></li>
            <li><a class="dropdown-item" href="#">Another action</a></li>
            <li><hr class="dropdown-divider"></li>
            <li><a class="dropdown-item" href="#">Something else here</a></li>
          </ul>
        </li>
        <li class="nav-item">
          <a class="nav-link disabled">Disabled</a>
        </li>
      </ul>

Вывод bootstrap 5 navbar при помощи pdoMeny будет следующим:

[[!pdoMenu?
    &level=`2`
    &parents=`0`
    &firstClass=`0`
    &lastClass=`0`
    &rowClass=`nav-item`
    &tpl=`@INLINE <li itemprop="name"[[+classes]]><a class="nav-link" href="[[+link]]"[[+attributes]]>[[+menutitle]]</a>[[+wrapper]]</li>`
    &parentClass=`dropdown`
    &outerClass=`navbar-nav me-auto mb-2 mb-lg-0`
    &tplOuter=`@INLINE <ul[[+classes]] itemtype="http://schema.org/SiteNavigationElement" itemscope="itemscope">[[+wrapper]]</ul>`
    &tplInner=`@INLINE <ul class="dropdown-menu" aria-labelledby="navbarDropdown">[[+wrapper]]</ul>`
    &tplInnerRow=`@INLINE <li><a itemprop="url" class="dropdown-item" href="[[+link]]"[[+attributes]]>[[+menutitle]]</a></li>[[+wrapper]]`
    &tplParentRow=`@INLINE <li[[+classes]]><a itemprop="url" class="nav-link dropdown-toggle" href="[[+link]]" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false"[[+attributes]]>[[+menutitle]]</a>[[+wrapper]]</li>`
]]

Внедрение микроразметки schema.org в MODX меню

Простенькое меню с микроразметкой выглядит так:

<ul itemtype="http://schema.org/SiteNavigationElement" itemscope="itemscope">
   <li itemprop="name"><a itemprop="url" href="#">Link1</a></li>
   <li itemprop="name"><a itemprop="url" href="#">Link2</a></li>
</ul>

С внедрением такой разметки думаю проблем не возникнет, а вот уже многоуровеневое меню имеет более сложную разметку, выглядит она так:

<nav itemscope="" itemtype="http://schema.org/SiteNavigationElement">
	<ul itemprop="about" itemscope="" itemtype="http://schema.org/ItemList">
		<li itemprop="itemListElement" itemscope="" itemtype="http://schema.org/ItemList">
			<a href="https://web-revenue.ru/" itemprop="url"><span itemprop="name">Главная</a></span>
		</li>		
		<li itemprop="itemListElement" itemscope="" itemtype="http://schema.org/ItemList">
			<a href="https://web-revenue.ru/information/" itemprop="url"><span itemprop="name">Информация</a></span>			
			<ul itemprop="itemListElement" itemscope="" itemtype="http://schema.org/ItemList">
				<li itemprop="itemListElement" itemscope="" itemtype="http://schema.org/ItemList">
					<a href="https://web-revenue.ru/information/uchebnye-stati/" itemprop="url"><span itemprop="name">Учебные статьи</a></span>
				</li>				
				<li itemprop="itemListElement" itemscope="" itemtype="http://schema.org/ItemList">
					<a href="https://web-revenue.ru/information/spravochnyj-centr/" itemprop="url"><span itemprop="name">Справочный центр</a></span>
				</li>
			</ul>
		</li>		
		<li itemprop="itemListElement" itemscope="" itemtype="http://schema.org/ItemList">
			<a href="https://web-revenue.ru/kontakty/" itemprop="url"><span itemprop="name">Контакты</a></span>			
		</li>
	</ul>
</nav>

Здесь уже сложнее и не каждый додумается как внедрить.

Вывод 2-х уровневого bootstrap 5 меню со schema.org

Здесь нам уже нужно захватить вместе с меню его дочерний элемент div, и он должен получиться следующим.

<div class="collapse navbar-collapse" id="navbarSupportedContent">
    [[!pdoMenu?
        &level=`2`
        &parents=`0`
        &firstClass=`0`
        &lastClass=`0`
        &rowClass=`nav-item`
        &tpl=`@INLINE <li itemprop="name"[[+classes]]><a class="nav-link" href="[[+link]]"[[+attributes]]>[[+menutitle]]</a>[[+wrapper]]</li>`
        &parentClass=`dropdown`
        &outerClass=`navbar-nav ms-auto mb-2 mb-lg-0`
        &tplOuter=`@INLINE <ul[[+classes]] itemprop="about" itemscope="" itemtype="http://schema.org/ItemList">[[+wrapper]]</ul>`
        &tplInner=`@INLINE <ul class="dropdown-menu" aria-labelledby="navbarDropdown" itemprop="itemListElement" itemscope="" itemtype="http://schema.org/ItemList">[[+wrapper]]</ul>`
        &tplInnerRow=`@INLINE <li itemprop="itemListElement" itemscope="" itemtype="http://schema.org/ItemList"><a itemprop="url" class="dropdown-item" href="[[+link]]"[[+attributes]]><span itemprop="name">[[+menutitle]]</span></a></li>[[+wrapper]]`
        &tplParentRow=`@INLINE <li[[+classes]] itemprop="itemListElement" itemscope="" itemtype="http://schema.org/ItemList"><a itemprop="url" class="nav-link dropdown-toggle" href="[[+link]]" id="navbarDropdown" role="button" data-bs-toggle="dropdown" aria-expanded="false"[[+attributes]]><span itemprop="name">[[+menutitle]]</span></a>[[+wrapper]]</li>`
    ]]
</div>

Проверить правильность микроразметки можно в инструментах от яндекс и google.

Css код для тех кто хочет, чтобы меню выпадало при наведении курсора мышки.

.dropdown:hover > .dropdown-menu {display:block;}

Так же в следующем уроке я приведу вывод нестандартного многоуровневого (с неограниченной вложенностью) на bootstrap 3, это для тех кто не уловил суть.

Трехуровневое (многоуровневое) меню с валидной микроразметкой.

Данное меню из шаблона Eterna (для 2х уровней нужно выставлять атирбуты rel="category").

<nav class="nav-menu d-none d-lg-block" itemscope itemtype="http://schema.org/SiteNavigationElement">
  <ul itemprop="about" itemscope itemtype="http://schema.org/ItemList">
    {'!pdoMenu' | snippet : [
        'level' => 3,
        'parents' => 0,
        'firstClass' => '0',
        'lastClass' => '0',
        'tpl' => '@INLINE <li itemprop="itemListElement" itemscope="" itemtype="http://schema.org/ItemList"{$classes}><a href="{$link}"{$attributes}>{$menutitle}</a><meta itemprop="name" content="{$menutitle}"/>{$wrapper}</li>',
        'parentClass' => 'drop-down',
        'tplOuter' => '@INLINE {$wrapper}',
        'tplInner' => '@INLINE <ul>{$wrapper}</ul>',
        'tplInnerRow' => '@INLINE <li itemprop="itemListElement" itemscope="" itemtype="http://schema.org/ItemList"{$classes}><a itemprop="url" href="{$link}" {$attributes}>{$menutitle}</a><meta itemprop="name" content="{$menutitle}"/></li>{$wrapper}',
        'tplParentRow' => '@INLINE <li itemprop="itemListElement" itemscope="" itemtype="http://schema.org/ItemList"{$classes}><a itemprop="url" href="{$link}" {$attributes}>{$menutitle}</a><meta itemprop="name" content="{$menutitle}"/>{$wrapper}</li>',
        'tplCategoryFolder' => '@INLINE <li itemprop="itemListElement" itemscope="" itemtype="http://schema.org/ItemList" class="drop-down"><a itemprop="url" href="{$link}" {$attributes}>{$menutitle}</a><meta itemprop="name" content="{$menutitle}"/>{$wrapper}</li>'
    ]}
</ul>
</nav>

Совет. Комментируйте код своего меню <!—код меню—> делайте свой вывод, если что-то не работает сравнивайте его с закомментированным и правьте недочеты.

Вывод многоуровневого Bootstrap 3 меню (с неограниченной вложенностью).

Вывод многоуровневого меню будет таким:

[[pdoMenu? 
&level=`5` 
&parents=`0` 
&firstClass=`0` 
&lastClass=`0` 
&parentClass=`dropdown` 
&outerClass=`nav navbar-nav` &levelClass=`submenu` 
&tplOuter=`@INLINE <ul [[+classes]]>[[+wrapper]]</ul>` 
&tplInner=`@INLINE <ul class="dropdown-menu">[[+wrapper]]</ul>` 
&tplParentRow=`@INLINE <li [[+classes]]><a class="dropdown-toggle" data-toggle="dropdown" href="[[+link]]" [[+attributes]]>[[+menutitle]]<span class="caret"></span></a>[[+wrapper]]</li>` 
]]

Из коробки оно работать не будет. так как Bootstrap 3 по умолчанию поддерживает только 2 уровня вложенности, и для того что бы расширить уровень вложенности bootstrap 3 меню, необходимо подключить js файл со следующим содержанием.

(function($){ 
$(document).ready(function(){ 
$('ul.dropdown-menu [data-toggle=dropdown]').on('click', function(event) { 
event.preventDefault(); 
event.stopPropagation(); 
$(this).parent().siblings().removeClass('open'); 
$(this).parent().toggleClass('open'); 
});
 }); 
})(jQuery);

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

В моем случае получилось 2 строки CSS кода, чтобы уровни выпадали в бок.

ul.dropdown-menu {left: 100%;top: -8px;}
li.submenu1.dropdown.open>ul.dropdown-menu {left: 0%; top: 100%;}

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

Видео

В моем видео вышло вот такое меню

menyu

Если вам нужно повернуть треугольнички в выпадающем меню (они направлены в низ, когда выпадают элементы влево), что бы получилось вот так.

Многоуровневое bootstrap меню в MODX

Тогда добавьте следующий css код:

li.submenu2.dropdown>a>span.caret {
-moz-transform:rotate(-95deg);
-ms-transform:rotate(-95deg);
-webkit-transform:rotate(-95deg);
-o-transform:rotate(-95deg);
transform:rotate(-95deg)
}

li.submenu3.dropdown>a>span.caret {
-moz-transform:rotate(-95deg);
-ms-transform:rotate(-95deg);
-webkit-transform:rotate(-95deg);
-o-transform:rotate(-95deg);
transform:rotate(-95deg)
}

li.submenu4.dropdown>a>span.caret {
-moz-transform:rotate(-95deg);
-ms-transform:rotate(-95deg);
-webkit-transform:rotate(-95deg);
-o-transform:rotate(-95deg);
transform:rotate(-95deg)
}

В следующем уроке разберем сниппет pdoResources.

Поделиться с друзьями
Алексей

Веб-дизайнер и SEO оптимизатор. Занимаюсь созданием сайтов с 2010 года и их продвижение с 2012 года!

Оцените автора
( 12 оценок, среднее 5 из 5 )
Web-Revenue.ru
Добавить комментарий

  1. Александр Прокопенко

    Статья отличная! Всё доступно и понятно! Но вот когда структура меню нестандартная, а как «матрёшка» — тогда уже не понятно!((( Если будет минутка у кого — посмотрите пожалуйста, как это можно через pdomenu вывести:

    Ответить
    1. Голягин Алексей

      Возьмите за основу код вывода 2х уровневого bs меню https://web-revenue.ru/modx-revo/modx-menyu#bootstrap-4-vypadayuschee-menyu-na-modx разметку немного поправьте) Еще есть платный компонент https://modstore.pro/packages/ecommerce/plcustommenu, можете попробовать его, если при помощи PdoMenu не можете разметку собрать)

      Ответить
  2. Виталий

    Здравствуйте, Алексей. Учусь по Вашим урокам, очень полезные. Столкнулся с проблемой…. Не могу вывести class с полей (( Может Вы, а может кто-то из читателей сталкивались с такой проблемой, буду очень благодарен за ответ.

    Имеется: [[wp съел код]]

    Сделал:

    [[pdoMenu?
    &parents=`0`
    &level=`1`
    &outerClass=’extend-container p-relative d-flex flex-column justify-content-center h-100′
    ]]

    На этом остановился(

    Ответить
    1. Алексей автор

      Здравствуйте. Еще раз напишите код разметки меню, только предварительно пропустите его через https://highlight.hohli.com/ — а то форма комментариев, его съела.

      Ответить
  3. Eвдакия

    Наконец-то! Единственное нормальное пояснение из всего рунета…Автор, спасибо большое!

    Ответить
    1. Алексей автор

      Пожалуйста)

      Ответить
  4. Yulya

    Здравствуйте, скажите пожалуйста, как вывести этот меню, на основе bootstrap 4. Заранее благодарю.

    Ответить
    1. Алексей автор

      Здравствуйте. Форма комментирования ест код. Можете мне в вк написать, я вам там подскажу.

      Ответить
  5. Юрий

    Здравствуйте! Сделал меню по Вашему уроку. Все получилось, кроме одного момента:
    Не выводятся ссылки на том пункте меню, который является контейнером для подпунктов:

    [[pdoMenu? 
        &level=`2` 
        &parents=`0`
        &displayStart=`1`
        &outerClass=`nav navbar-nav mr-auto`
        &tplOuter=`@INLINE [[+wrapper]]` 
        &tplInner=`@INLINE [[+wrapper]]`
        &tplParentRow=`@INLINE <a href="[[+link]]" rel="nofollow ugc">[[+menutitle]]</a>[[+wrapper]]`
        &tplParentRowActive=`@INLINE <a href="[[+link]]" rel="nofollow ugc">[[+menutitle]]</a>[[+wrapper]]`
        &tplInnerRow=`@INLINE <a href="[[+link]]" rel="nofollow ugc">[[+menutitle]]</a>[[+wrapper]]`
    ]]

    Можете подсказать, что неправильно сделано?

    Ответить
    1. Алексей автор

      Половину кода съела форма, так что не подскажу

      Ответить
  6. VoodooSystem

    Добрый день. Вопрос может кто сталкивался уже? Существует проблема в данный момент, при использовании сниппета pdoMenu (как и устаревшего аналогичного wayfinder), на странице перестает работать другой скрипт фильтрации данных css filters-list… Просто «отваливается» его функциональность, при статичном же меню все ок… что это? Несовместимость обработки php или конфликт классов какой-то?

    Ответить
    1. Алексей автор

      Скорее вы не правильно конструкцию меню выводите) Сделал более 50 сайтов с различными меню (в том числе с мега меню) и все норм. Да и вызывайте сниппет не кэшируемым.

      Ответить
      1. VoodooSystem

        Вы имеете ввиду неправильное распределение классов элементов ul и li? Но парадокс в том что другой скрипт на странице «отваливается» именно во время корректной работоспособности, именно после интеграции pdopage или wayfinder с 2 и 3-ех уровнями… тоесть меню работает, скрипт фильтрации галереи prettyphoto в это время нет =/ при обычном коде (без сниппета) все ок.

        Ответить
        1. Алексей автор

          PdoMenu ничего не добавляет в код — следовательно не может нарушить работу сторонних скриптов. Если не работает меню — значит вы не правильно его строите. Если отваливается какой нибудь скрипт — значит искать проблему нужно в другом месте.

          Ответить
  7. Денис

    Добрый день. Могли бы вы мне подсказать?

    Я делаю свой первый сайт на modx. Обрезал весь комментарий — не вижу проблемы на вашем сайте которая указана в комментарии.

    Ответить
    1. Денис

      Ребята. Нашел решение. Подсказали на форуме
      Нужно Добавить в head:

      Добавил, в теперь все работает как надо!

      Ответить
      1. Алексей автор

        Код из комментариев вырезается к сожалению. У вас не хватала тега base? правильно?

        Ответить