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

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

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

Создавать динамическое меню в 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`
]]

Официальную документацию можете почитать [mask_link href=»https://docs.modx.pro/komponentyi/pdotools/snippetyi/pdomenu» target=»_blank»]здесь[/mask_link]. А сейчас разберем самые типовые вызовы меню.

Вызов PdoMenu

Вариант 1. На месте этого статического меню вызовем сниппет pdoMenu, для этого в дереве ресурсов, на вкладке “Элементы” в разделе сниппеты разверните ветку pdoTools, далее нажмите на 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>`
]]

[spoiler title=»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>'
]}

[/spoiler]

где:

  • &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>`
]]

[spoiler title=»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>'
]}

[/spoiler]

Пример 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

Если убрать обвертку с бургером (кнопкой) и окошко поиска, то статический 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;}

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

Данное меню из шаблона 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 классы в коде, к которым нужно применить стили показано в видео, ну а если быть точнее то там показан весь процесс создания многоуровневого меню.

Видео

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

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

Тогда добавьте следующий 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 года!

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

  1. This is really interesting, You’re an excessively professional blogger. I’ve joined your rss feed and look forward to in search of extra of your wonderful post. Additionally, I have shared your web site in my social networks!

  2. Статья отличная! Всё доступно и понятно! Но вот когда структура меню нестандартная, а как «матрёшка» — тогда уже не понятно!((( Если будет минутка у кого — посмотрите пожалуйста, как это можно через 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 не можете разметку собрать)

  3. Здравствуйте, Алексей. Учусь по Вашим урокам, очень полезные. Столкнулся с проблемой…. Не могу вывести 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/ — а то форма комментариев, его съела.

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

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

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

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

    [[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]]`
    ]]

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

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

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

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

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

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

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

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

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

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

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Exit mobile version