Как реализовать меню 3 уровня средствами используя один шаблон?

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

Структура будет такая

Главная
Категория
	Подкатегория-1
		Под-подкатегория-1
		Под-подкатегория-2
	Подкатегория-2
		Под-подкатегория-1
		Под-подкатегория-2
Категория-2
Категория-3
Это 1 уровень меню:



После нажатия на категорию появляется подпункт меню, и выделяется активный пункт категории.



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



Пытался сделать несколькими вызовами pdoMenu, с условиями на fenom но больно много условий if и приходится привязываться к id, что заставляет сделать несколько шаблонов.

Может кто нибудь сталкивался с подобной задачей, что то подскажет?
Сергей
31 мая 2018, 17:23
modx.pro
1
3 137
+1

Комментарии: 22

Andrey
01 июня 2018, 00:07
+1
Я реализовал вот так:
[[pdoMenu?
        &level=`2`
        &tplOuter=`lk.Outer`
        &tpl=`lk.Row`
        &tplParentRow=`lk.ParentRow`
        &tplInner=`lk.InnerOuter`
        &tplInnerRow=`lk.InnerRow`
        &tplStart=`lk.tplStart`
        &displayStart=`1`
]]
Где:
Отвечает за самый верхний уровень:
&tplStart=`lk.tplStart`
За второй уровень:
&tplOuter=`lk.Outer`
За третий уровень и т.д.:
&tplOuter=`lk.Outer`
Если у вас разные шаблоны ввода второго уровня (например как у меня, шаблон при выводе второго уровня меняется ввиду того, что к элементу меню второго уровня добавляется третий, т.е. появляются дочерки):
&tplParentRow=`lk.ParentRow`
При этом важно, чтобы работал параметр:
&displayStart=`1`
Иначе такая конструкция не поможет.
Все необходимые плейсхолдеры есть в документации, как и данные параметры:
pdomenu
    Сергей
    01 июня 2018, 01:05
    0
    Спасибо! А можно посмотреть как реализовано?
      Сергей
      01 июня 2018, 09:59
      0
      Не знаю у меня ни чего не получилось, может что то не правильно делаю…
      Набросал меню
      <div class="wrapper-menu">
          <div style="background:#ccc; max-width:100%; height: auto;" class="menuTop">
              <ul style="position:relative;">
                  <li style="display:inline-block;"><a style="padding-left:20px;" href="">LINK</a></li>
                  <li style="display:inline-block;"><a style="padding-left:20px;" href="">LINK</a>
                      <div style="background: #8ef1f1;
                          width: 100%;
                          height: auto;
                          position: absolute;
                          left: 0;" class="menuLevel2">
                          <ul style="position:relative;">
                              <li style="display:inline-block;"><a style="padding-left:20px;" href="">LINK</a></li>
                              <li style="display:inline-block;"><a style="padding-left:20px;" href="">LINK</a>
                          </ul>
                      </div>
                  </li>
              </ul>
          </div>
      </div>
      Вот его вызов по вашему примеру
      [[pdoMenu?
              &level=`2`
              &tplOuter=`@INLINE  <div class="wrapper-menu">[[+wrapper]]</div>`
              &tpl=`@INLINE   <li style="display:inline-block;">
                                  <a style="padding-left:20px;" href="[[+link]]">[[+menutitle]]</a>
                              </li>`
              &tplParentRow=` <li style="display:inline-block;">
                                  <a style="padding-left:20px;" href="[[+link]]">[[+menutitle]]</a>
                                     <div style="background: #8ef1f1; 
                                         width: 100%; 
                                         height: auto; 
                                         position: absolute; 
                                         left: 0;" class="menuLevel2">[[+wrapper]]</div>
                              </li>`
              &tplInner=`@INLINE <div style="background: #8ef1f1; 
                                         width: 100%; 
                                         height: auto; 
                                         position: absolute; 
                                         left: 0;" class="menuLevel2">[[+wrapper]]</div>`
              &tplInnerRow=`@INLINE <div style="background:#ccc; max-width:100%; height: auto;" class="menuLevel2">
                                      <ul style="position:relative;">
                                          <li style="display:inline-block;">
                                              <a style="padding-left:20px;" href="[[+link]]">[[+menutitle]]</a>
                                          </li>
                                      </ul>
                                  </div>`
              &tplStart=`@INLINE  <div style="background:#ccc; max-width:100%; height: auto;" class="menuTop">
                                      <ul style="position:relative;">
                                          <li style="display:inline-block;">
                                              <a style="padding-left:20px;" href="[[+link]]">[[+menutitle]]</a>
                                          </li>
                                      </ul>
                                  </div>[[+wrapper]]`
              &displayStart=`1`
      ]]
      Вот что получилось сайт

      Логин: menu
      Пароль: menumenu

      Вся конструкция находится в чанке
      Content.main
    Oleg
    01 июня 2018, 13:34
    +1
    {'!pdoMenu' | snippet : [
    	'parents' => 0,
    	'level' =>3,
    	'templates'=>-6,
    	'tplOuter'=>'@INLINE <ul>{$wrapper}</ul>',
    	'tpl'=>'@INLINE <li><a href="{$link}">{$menutitle}</a>{$wrapper}</li> ',
    	'tplParentRow'=>'@INLINE <li class="main_menu__parent"><a href="{$link}">{$menutitle}</a>{$wrapper}</li>',
    ]}
    <nav class="col-md-12 col-lg-10 col-xl-9 main_menu">
    	<div id="mobile_menu">Меню</div>
    	<ul>
    		<li><a href="/">Главная</a></li><li><a href="produkcziya/">Продукция</a></li>
    		<li><a href="dokumentacziya">Документация</a></li>
    		<li class="main_menu__parent"><a href="/kachestvo/">Качество</a>
    			<ul>
    				<li><a href="politika-v-oblasti-kachestva-i-ekologii">Политика в области качества и экологии</a></li>
    				<li><a href="laboratoriya">Лаборатория</a></li>
    			</ul>
    		</li>
    		<li><a href="zakazyi">Заказы</a></li><li><a href="kontaktyi/">Контакты</a></li>
    	</ul>
    </nav>
      Сергей
      01 июня 2018, 15:19
      0
      Спасибо за помощь!
      Ваш пример это обычный вывод меню к примеру в Bootstrap.Theme Василия.
      У Вас идет привязка к шаблону, а мне нужно сделать это динамически без привязки.
      С горем пополам получилось вот так, но мне кажется данная конструкция не правильная!

      <div class="wrapper">
      
          
          {'!pdoMenu' | snippet : [
          	'parents' => $_modx->resources.id,
          	'level' => 1,
          	'hereClass' => 'active',
          	'tplOuter'=>'@INLINE    <div class="level_1">
                                          <div class="container">
                                              <ul>{$wrapper}</ul>
                                          </div>
                                      </div>',
          	'tpl'=>'@INLINE <li><a {$classes} href="{$link}"><h2>{$menutitle}</h2></a></li> '
          ]}
          
              {set $id = $_modx->resource.id}
              {if $id == 4}
                  {'!pdoMenu' | snippet : [
                  	'parents' => $_modx->resource.id,
                  	'level' => 2,
                  	'hereClass' => 'active',
                  	'tplOuter'=>'@INLINE    <div class="level_2">
                                                  <div class="container">
                                                      <ul>{$wrapper}</ul>
                                                  </div>
                                              </div>',
                  	'tpl'=>'@INLINE <li><a {$classes} href="{$link}">{$menutitle}</a></li> '
                  ]}
              {else}
                  {'!pdoMenu' | snippet : [
                  	'parents' => ($_modx->resource.parent | resource : "id"),
                  	'level' => 2,
                  	'hereClass' => 'active',
                  	'tplOuter'=>'@INLINE    <div class="level_2">
                                                  <div class="container">
                                                      <ul>{$wrapper}</ul>
                                                  </div>
                                              </div>',
                  	'tpl'=>'@INLINE <li><a {$classes} href="{$link}">{$menutitle}</a></li> '
                  ]}
              {/if}
              
                  
      </div>
      Вот что получилось

      А и стили
      <style>
          .wrapper {
              width: 100%;     
          }
          
          .level_1 {
              background: #ccc;
          }
          
          .level_1 ul {
              position: relative;
          }
          
          .level_1 ul li {
              display: inline-block;
              padding-left: 10px;
          }
          
          .level_1 ul li a.active {
              color: red;
          }
          
          .level_2 {
              background: #eee;
          }
          
          .level_2 ul {
              position: relative;
          }
          
          .level_2 ul li {
              display: inline-block;
              padding-left: 10px;
              padding-top: 10px;
          }
          
          .level_2 ul li a.active {
              color: green;
          }
      
      </style>
        Oleg
        01 июня 2018, 15:26
        0
        Я не совсем понимаю задачи.
        Вам нужно на каждой странице свое особенное меню?
        Не совсем этого догоняю.
        Если да, то почему бы каждый вызов не обернуть в чанк и использовать и в зависимости от необходимости?
        Как вариант.
        Если честно задача мне не понятная. =_(

        UPD. Зачем чередовать два абсолютно одинаковых вызова? О_о Или я чего-то не заметил?
        UPD2. Ага. Кажется догнал.
        Вы хотите трех уровневое меню.
        Только объясните мне что вам запрещает использовать шаблон? Это легко реализуется на js.
          Сергей
          01 июня 2018, 15:47
          0
          Ну можно и в чанк, только это дополнительная вложенность.
          Я уже сам не понимаю...)))

          Ну например есть меню 1 уровень:

          Главная | Услуги | Контакты

          При нажатии на услуги нужно что бы появилось другое меню, но начальное осталось на месте, т.е.:

          Главная | Услуги | Контакты
          — подуслуга-1 | подуслуга-2 | подуслуга-3

          При нажатии на подуслугу, должно быть так:

          Главная | Услуги | Контакты
          — подуслуга-1 | подуслуга-2 | подуслуга-3

          Как это реализовать?

          PS Че то я заморочился????)))

            Oleg
            01 июня 2018, 15:49
            +1
            Есть у меня одна мысль. Щас все будет — я надеюсь))
              Сергей
              01 июня 2018, 15:51
              0
              Логин menu
              Пароль menumenu
              Сайт
                Сергей
                01 июня 2018, 15:53
                0
                Нашел ошибку в моем решении, теряется вложенность.....
                Обновил кеш все нормально!
                  Сергей
                  01 июня 2018, 16:04
                  0
                  Исправил на
                  {if $id == ''}
                  , работает id указывать не нужно.
                  Создал еще категорию ТОВАРЫ и ему подпункты, все работает отлично!
                    Oleg
                    01 июня 2018, 16:29
                    +1
                    Хм…
                    Я тут пока дошел только до начальной стадии.

                    Но мне кажется, что я иду не верным путем)
                      Сергей
                      01 июня 2018, 16:46
                      0
                      Ну не стоит так переусердствовать из за меня, если только самому стало интересно!)))
                      Oleg
                      01 июня 2018, 16:30
                      0
                      АААААААА! Вот оно как вы хотели)
                      Ну… я еще подумаю над тем как можно это реализовать)
                        Oleg
                        01 июня 2018, 16:31
                        0
                        Вам нужна именно подгрузка содержимого самой страницы в этот момент?
                          Сергей
                          01 июня 2018, 16:45
                          0
                          Ну естественно! Чем то напоминает хлебные кроши, я вот думаю скорее всего можно данным компонентом тоже решить…
                Oleg
                01 июня 2018, 15:35
                0
                Извините, задачка интересная. Нужно подумать.
                  Николай
                  21 июня 2018, 10:58
                  0
                  Подскажите пожалуйста, как одним вызовом сделать:
                  [[pdoMenu?
                  &parents=`8,9`
                  ...
                  ]]
                  [[pdoMenu?
                  &parents=`10,12`
                  ...
                  ]]
                  [[pdoMenu?
                  &parents=`13,14,15,16,17,18,19`
                  ...
                  ]]
                    Oleg
                    21 июня 2018, 11:14
                    0
                    Скорее всего никак.
                    Вы скармливаете спиппету параметры.
                    Спиппет их обрабатывает и выдает новые.

                    В цикле его оформить никак не могу представить даже.
                      Николай
                      21 июня 2018, 11:21
                      0


                      Вот такое у меня меню каждая колонка это один вызов pdoMenu:
                      [[pdoMenu?
                      &parents=`10,12`
                      &level=`1`
                      &firstClass=``
                      &lastClass=``
                      &displayStart=`1`
                      &tplStart=`@INLINE <li[[+classes]]><a href="[[+link]]">[[+menutitle]]</a>[[+wrapper]]</li>`
                      &tplOuter=`@INLINE <ul>[[+wrapper]]</ul>`
                      &tpl=`@INLINE <li[[+classes]]><a href="[[+link]]">[[+menutitle]]</a>[[+wrapper]]</li>`
                      ]]
                        Oleg
                        21 июня 2018, 11:26
                        0
                        Я бы это осуществил бы немного по другому.
                        Например я бы просто вызвал бы pdoMenu
                        И пользуясь возможностью указывать шаблоны на каждый особенный случай пошаманил бы в CSS.

                        Что вам конкретно нужно?
                        Тут уже больше проблема не в MODX и сниппете, а в HTML и CSS на мой взгляд
              Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
              22