pdoMenu - Using different

Hi all,

I’m using pdoMenu for my navigation bar. I’m just wondering is it possible to have 2 different layouts in the same pdoMenu code?

Below is my family tree layout. I want to use the same layout for most pages, a simple dropdown but I want a different layout for the Competition page and all the pages connected to it. Is it possible to have 2 rowTpl, innerTpl in the same pdoMenu snippet?

I HOPE THIS MAKES SENSE.

  • Home
  • About Us (parent)
    *** Food (child)
    *** Accommodation (child)
  • Competition (parent)
    *** National (child)
    ****** Semi Final (inner child)
    ****** Final (inner child)
    *** Dublin (child)
    ****** Semi Final (inner child)
    ****** Final (inner child)
    *** Galway (child)
    ****** Semi Final (inner child)
    ****** Final (inner child)
  • Archive
  • Contact Us
1 Like

Maybe you can use output modifiers in your menu templates to output different markup. For example by using the template of the page:

[[+template:is=`2`:then=`output some markup`:else=`output some other markup`]]

Or you could try if it works with nested pdoMenu calls. Like in this topic:

I’m going to have to spend some time on this. I’ve been looking at the documents on https://docs.modx.pro/en/components/pdotools/snippets/pdomenu

I have another problem too. My competition parent and child pages will have three <ul></ul> tags. I can use outerTpl for the first one and innerTpl for the second but anyone have any ideas what I could use for the third?

Same code below: It has three <ul></ul> with three different classes.

<ul class="menu-container"> <outerTpl><start>
  <li class="menu-item mega-menu"> <parentRowTpl><start>
    <a class="menu-link" href="#"><div>Competition</div></a>
    <div class="mega-menu-content mega-menu-style-2">
      <div class="container">
        <div class="row">
          <ul class="sub-menu-container mega-menu-column col-lg-3"> <innerTpl><start>
            <li class="menu-item mega-menu-title"> <parentRowTpl><start>
              <a class="menu-link" href="#"><div>National</div></a>
              <ul class="sub-menu-container"> <innerTpl><start>
                <li class="menu-item"><a class="menu-link" href="#"><div>Semi-Final</div></a></li>
                <li class="menu-item"><a class="menu-link" href="#"><div>Final</div></a></li>
              </ul> <innerTpl><end>
            </li> <parentRowTpl><end>
          </ul> <innerTpl><end>
        </div>
      </div>
    </div>
  </li> <parentRowTpl><end>
</ul> <outerTpl><end>

But I then have another page called Teams and that has two <ul></ul> tags and both classes are the same as the competitions page but the second <ul></ul> tag doesn’t have the div’s before it. I need those divs for the layout of my navigation but I only need them for the competitions page. Code below.

<ul class="menu-container"> <outerTpl><start>
  <li class="menu-item mega-menu"> <parentRowTpl><start>
    <a class="menu-link" href="#" title="Teams" ><div>Teams</div></a>
      <ul class="sub-menu-container"> <innerTpl><start>
        <li class="menu-item"><a class="menu-link" href="#" title="Team A" ><div>Team A</div></a></li> <rowTpl><start><end>
        <li class="menu-item"><a class="menu-link" href="#" title="Team B" ><div>Team B</div></a></li> <rowTpl><start><end>
      </ul> <innerTpl><end>
  </li> <parentRowTpl><end>
</ul> <outerTpl><end>

There is a placeholder for the level [[+level]] that you can use for that.

[[pdoMenu?
    &parents=`1`
    &tplOuter=`@INLINE <ul class="level0-class">{{+wrapper}}</ul>`
    &tplInner=`@INLINE <ul class="{{+level:is=`1`:then=`level1-class`}}{{+level:is=`2`:then=`level2-class`}}">{{+wrapper}}</ul>`
]]

There are also other placeholders available like [[+id]] that you can use in the template to conditionally add some markup for a specific resources.

There’s also the handy &levelClass property which you can add to the call to automatically add the level classes to the rows.

[[pdoMenu?
  &parents=`0`
  &level=`3`
  &parentClass=`parent`
  &levelClass=`level-`
]]

Using the default templates, this will output the following three-level menu:

<ul class="">
	<li class="first level-1">
		<a href="index.php?id=1" >Home</a>
	</li>
	<li class="last level-1 parent">
		<a href="index.php?id=2" >Testing</a>
		<ul class="">
			<li class="first level-2 parent">
				<a href="index.php?id=3" >Testing Child</a>
				<ul class="">
					<li class="first level-3">
						<a href="index.php?id=4" >Testing Child Child</a>
					</li>
				</ul>
			</li>
		</ul>
	</li>
</ul> 

With CSS background colours applied to the different level classes - it might look like this:

image

If you then wanted to override the styles for certain resources - you can add output modifiers to add additional classes to the <li> tags in your row templates like @halftrainedharry suggested - for instance:

<li class="[[+parent:is=`3`:then=` competition-page-class `]]">

*assumes Competition page ID is 3

Then just add your CSS declarations for competition-page-class after your level-1, level-2 and level-3 ones.

PS …

I think, if specified, tplInner is used for the second, third and any subsequent levels of them menu.

tplInnerRow is likely where you’ll want to use output modifiers to add extra CSS classes for your Competition pages.

I’m getting there. The only issue I have now are the DIVS. I just can’t seem to get them in. Below is my complete navigation bar code. This is what it should be.

<nav class="primary-menu">
  <ul class="menu-container">
    <li class="menu-item "><a class="menu-link" href="#" title="Home" ><div>Home</div></a></li>
    <li class="menu-item "><a class="menu-link" href="#" title="Information" ><div>Information</div></a>
      <ul class="sub-menu-container">
        <li class="menu-item "><a class="menu-link" href="#" title="Accommodation" ><div>Accommodation</div></a></li>
        <li class="menu-item "><a class="menu-link" href="#" title="Food" ><div>Food</div></a></li>
      </ul>
    </li>
    <li class="menu-item "><a class="menu-link" href="#" title="Teams" ><div>Teams</div></a>
      <ul class="sub-menu-container">
        <li class="menu-item "><a class="menu-link" href="#" title="Team A" ><div>Team A</div></a></li>
        <li class="menu-item "><a class="menu-link" href="#" title="Team B" ><div>Team B</div></a></li>
      </ul>
    </li>
    <li class="menu-item mega-menu"><a class="menu-link" href="#" title="Competition" ><div>Competitiom</div></a>
      <div class="mega-menu-content mega-menu-style-2">
        <div class="container">
          <div class="row">
            <ul class="sub-menu-container mega-menu-column col-lg-3">
              <li class="menu-item "><a class="menu-link" href="#" title="National" ><div>National</div></a>
                <ul class="sub-menu-container">
                  <li class="menu-item "><a class="menu-link" href="#" title="Quarter Final" ><div>Quarter Final</div></a></li>
                  <li class="menu-item "><a class="menu-link" href="#" title="Semi Final" ><div>Semi Final</div></a></li>
                  <li class="menu-item "><a class="menu-link" href="#" title="Final" ><div>Final</div></a></li>
                </ul>
              </li>
              <li class="menu-item "><a class="menu-link" href="#" title="Local" ><div>Local</div></a>
                <ul class="sub-menu-container">
                  <li class="menu-item "><a class="menu-link" href="#" title="Quarter Final" ><div>Quarter Final</div></a></li>
                  <li class="menu-item "><a class="menu-link" href="#" title="Semi Final" ><div>Semi Final</div></a></li>
                  <li class="menu-item "><a class="menu-link" href="#" title="Final" ><div>Final</div></a></li>
                </ul>
              </li>
            </ul>        
          </div>
        </div>
      </div>
    </li>
    <li class="menu-item "><a class="menu-link" href="#" title="Contact Us" ><div>Contact Us</div></a></li>
  </ul>      
</nav>

I have used bits from each of you guys. I’m trying to use the placeholder [[+id]].

[[pdoMenu?
  &parents=`0`
  &level=`0`
  &tplOuter=`@INLINE <ul class="menu-container">[[+wrapper]]</ul>`
  &tplInner=`@INLINE <ul class="[[+id:is=`8`:then=`sub-menu-container mega-menu-column col-lg-3`:else=`sub-menu-container`]]">[[+wrapper]]</ul>`
  &tpl=`@INLINE <li class="menu-item [[+id:is=`8`:then=`mega-menu`:else=``]]"><a class="menu-link" href="[[+wf.link]]" title="[[+wf.title]]" [[+wf.attributes]]><div>[[+wf.linktext]]</div></a>[[+wf.wrapper]]</li>`
  &tplParentRow=`@INLINE [[+id:is=`8`:then=`<li class="menu-item mega-menu"><a class="menu-link" href="#"><div>Competition</div></a><div class="mega-menu-content mega-menu-style-2"><div class="container"><div class="row">   </div></div></div></li>`:else=`<li class="menu-item"><a class="menu-link" href="#" title="Teams" ><div>Teams</div></a></li>`]]`
]]

So when I use the pdoMenu above, everything seems to work fine except the DIVS don’t come through. The Competition Page is ID - 8. The above pdoMenu code produces the code below:

<nav class="primary-menu">
  <ul class="menu-container">
    <li class="menu-item "><a class="menu-link" href="#" title="Home" ><div>Home</div></a></li>
    <li class="menu-item "><a class="menu-link" href="#" title="Information" ><div>Information</div></a>
      <ul class="sub-menu-container">
        <li class="menu-item "><a class="menu-link" href="#" title="Accommodation" ><div>Accommodation</div></a></li>
        <li class="menu-item "><a class="menu-link" href="#" title="Food" ><div>Food</div></a></li>
      </ul>
    </li>
    <li class="menu-item "><a class="menu-link" href="#" title="Teams" ><div>Teams</div></a>
      <ul class="sub-menu-container">
        <li class="menu-item "><a class="menu-link" href="#" title="Team A" ><div>Team A</div></a></li>
        <li class="menu-item "><a class="menu-link" href="#" title="Team B" ><div>Team B</div></a></li>
      </ul>
    </li>
    <li class="menu-item mega-menu"><a class="menu-link" href="#" title="Competition" ><div>Competitiom</div></a>
      <ul class="sub-menu-container mega-menu-column col-lg-3">
        <li class="menu-item "><a class="menu-link" href="#" title="National" ><div>National</div></a>
          <ul class="sub-menu-container">
            <li class="menu-item "><a class="menu-link" href="#" title="Quarter Final" ><div>Quarter Final</div></a></li>
            <li class="menu-item "><a class="menu-link" href="#" title="Semi Final" ><div>Semi Final</div></a></li>
            <li class="menu-item "><a class="menu-link" href="#" title="Final" ><div>Final</div></a></li>
          </ul>
        </li>
        <li class="menu-item "><a class="menu-link" href="#" title="Local" ><div>Local</div></a>
          <ul class="sub-menu-container">
            <li class="menu-item "><a class="menu-link" href="#" title="Quarter Final" ><div>Quarter Final</div></a></li>
            <li class="menu-item "><a class="menu-link" href="#" title="Semi Final" ><div>Semi Final</div></a></li>
            <li class="menu-item "><a class="menu-link" href="#" title="Final" ><div>Final</div></a></li>
          </ul>
        </li>
      </ul>
    </li>
    <li class="menu-item "><a class="menu-link" href="#" title="Contact Us" ><div>Contact Us</div></a></li>
  </ul>      
</nav>

I JUST CAN’T GET THE DIVS IN!!!

Shouldn’t there be a placeholder [[+wrapper]] in your &tplParentRow?

Also, output modifiers in inline-templates can confuse the MODX parser. Maybe try using chunks instead or use tags with curly braces (e.g. {{+id:is=`8`:then=`...`}}) in the inline-template.

I think this gets all that markup you need:

[[pdoMenu?
  &parents=`0`
  &level=`0`
  &tplOuter=`@INLINE <ul class="menu-container">[[+wrapper]]</ul>`
  &tplInner=`sub-menu-container-tpl`
  &tpl=`@INLINE <li class="menu-item [[+id:is=`8`:then=`mega-menu`:else=``]]"><a class="menu-link" href="[[+wf.link]]" title="[[+wf.title]]" [[+wf.attributes]]><div>[[+wf.linktext]]</div></a>[[+wf.wrapper]]</li>`
]]

sub-menu-container-tpl chunk:

[[+id:is=`8`
:then=`<div class="mega-menu-content mega-menu-style-2"><div class="container"><div class="row"><ul class="sub-menu-container mega-menu-column col-lg-3">[[+wrapper]]</ul></div></div></div>`
:else=`<ul class="sub-menu-container">[[+wrapper]]</ul>`]]

Can I pick your brain again Lucy. I had to change my code slightly. I’m trying all sorts of placeholders but struggling to get the final bit I need done. I’m so close using the help you gave earlier. Below is my layout.

`<ul class="menu-container">
  <li class="menu-item"><a class="menu-link" href="#" ><div>Home (1)</div></a></li>
  <li class="menu-item"><a class="menu-link" href="#" ><div>Teams (2)</div></a>
    <ul class="sub-menu-container">
      <li class="menu-item "><a class="menu-link" href="#" ><div>Team One(4)</div></a></li>
      <li class="menu-item "><a class="menu-link" href="#" ><div>Team Two (5)</div></a></li>
    </ul>
  </li>
  <li class="menu-item mega-menu">
  	<a class="menu-link" href="#"><div>Competition (3)</div></a>
  	<div class="mega-menu-content mega-menu-style-2">
      <div class="container">
        <ul class="row list-unstyled">
          <li class="menu-item mega-menu-title mt-0 col-lg-3 mega-menu-column"><a class="menu-link" href="#"><div>National (6)</div></a>
            <ul class="sub-menu-container">
              <li class="menu-item"><a class="menu-link" href="#"><div>Semi-Final (10)</div></a>
                <ul class="sub-menu-container mega-menu-dropdown">
                  <li class="menu-item"><a class="menu-link" href="#"><div>Game 1 (18)</div></a></li>
                  <li class="menu-item"><a class="menu-link" href="#"><div>Game 2 (19)</div></a></li>
                </ul>
              </li>
              <li class="menu-item"><a class="menu-link" href="#"><div>Final (11)</div></a></li>
            </ul>
          </li>
          <li class="menu-item mega-menu-title mt-0 col-lg-3 mega-menu-column"><a class="menu-link" href="#"><div>Dublin (7)</div></a>
            <ul class="sub-menu-container">
              <li class="menu-item"><a class="menu-link" href="#"><div>Semi- (12)</div></a>
                <ul class="sub-menu-container mega-menu-dropdown">
                  <li class="menu-item"><a class="menu-link" href="#"><div>Game 1 (20)</div></a></li>
                  <li class="menu-item"><a class="menu-link" href="#"><div>Game 2 (21)</div></a></li>
                </ul>
              </li>
              <li class="menu-item"><a class="menu-link" href="#"><div>Final (13)</div></a></li>
            </ul>
          </li>
          <li class="menu-item mega-menu-title mt-0 col-lg-3 mega-menu-column"><a class="menu-link" href="#"><div>Kerry (8)</div></a>
            <ul class="sub-menu-container">
              <li class="menu-item"><a class="menu-link" href="#"><div>Semi-Final (14)</div></a>
                <ul class="sub-menu-container mega-menu-dropdown">
                  <li class="menu-item"><a class="menu-link" href="#"><div>Game 1 (22)</div></a></li>
                  <li class="menu-item"><a class="menu-link" href="#"><div>Game 2 (23)</div></a></li>
                </ul>
              </li>
              <li class="menu-item"><a class="menu-link" href="#"><div>Final (15)</div></a></li>
            </ul>
          </li>
          <li class="menu-item mega-menu-title mt-0 col-lg-3 mega-menu-column"><a class="menu-link" href="#"><div>Galway (9)</div></a>
            <ul class="sub-menu-container">
              <li class="menu-item"><a class="menu-link" href="#"><div>Semi-Final (16)</div></a>
                <ul class="sub-menu-container mega-menu-dropdown">
                  <li class="menu-item"><a class="menu-link" href="#"><div>Game 1 (24)</div></a></li>
                  <li class="menu-item"><a class="menu-link" href="#"><div>Game 2 (25)</div></a></li>
                </ul>
              </li>
              <li class="menu-item"><a class="menu-link" href="#"><div>Final (17)</div></a></li>
            </ul>
          </li>
        </ul>
      </div>
    </div>
  </li>
</ul>`

This is my pdoMenu layout.

[[pdoMenu?
  &parents=`0`
  &level=`0`
  &tplOuter=`outerTpl`
  &tplInner=`subMenuContainerTpl`
  &tpl=`@INLINE <li class="[[+id:is=`8`:then=`menu-item mega-menu`:else=`menu-item`]]"><a class="menu-link" href="[[+link]]" [[+attributes]]><div>[[+menutitle]]</div></a>[[+wrapper]]</li>`
]]   

My subMenuCintainerTpl is:

[[+id:is=`8`
:then=`<div class="mega-menu-content mega-menu-style-2"><div class="container"><ul class="row list-unstyled">[[+wrapper]]</ul></div></div>`
:else=`<ul class="sub-menu-container">[[+wrapper]]</ul>`]]

I have the ul’s working but the multiple li’s inside the mega menu is difficult.

So this is now 4 levels deep? My brain hurts. :sweat_smile:

There’s no way I know of to do this with a single pdoMenu call, unless all of your inner ULs and LIs use identical markup. In your case every level has different markup. The &tplInner wraps submenu sections on all inner levels, so you need a way to target the 4th level. You can do it with “nested” pdomenu calls, probably.

Have a look at this post, this is the general idea. A nested pdomenu call allows you to “start over” with another menu inside the first that has its parents further down in the tree, so you can then target all the levels with different outer and inner templates in each snippet call.
https://forums.modx.com/thread/103735/megamenu-bites-again#dis-post-558011

1 Like

Just and opinion, but at this point feels like trying to fit a tool to the problem, with some potential drawbacks, for example nested calls, are more resources, maybe not to much, but perfomance wise, everthing adds.

Wouldn’t, at this point be better to create a snippet that with a single query, returns a nested json structure that defines the menu, and can be easily processed and add any other needed logic like setting markup based on recursion level, etc?

Hey @coconghaile … is this your desired layout or what pdoMenu currently outputs?

Would it not be possible to use the aforementioned [[+level]] placeholder to specify a different tpl for each level?

So instead of:

&tpl=`@INLINE <li class="[[+id:is=`8`:then=`menu-item mega-menu`:else=`menu-item`]]"><a class="menu-link" href="[[+link]]" [[+attributes]]><div>[[+menutitle]]</div></a>[[+wrapper]]</li>`

change to:

&tpl=`navTpl`

and in navTpl - something like:

[[+id:isnot=`8`

:then=`

	[[- Your default LI and associated markup for non-Competition pages ]]
	<li class="menu-item [[+classnames]]"><a class="menu-link" href="[[+link]]" [[+attributes]]><div>[[+menutitle]]</div></a>[[+wrapper]]</li>

`:else=`

	[[+level:is=`1`:then=`
		[[- Your Level 1 LI and associated markup ]]
		<li class="menu-item mega-menu [[+classnames]]"><a class="menu-link" href="[[+link]]" [[+attributes]]><div>[[+menutitle]]</div></a>[[+wrapper]]</li>
	`]]


	[[+level:is=`2`:then=`
		[[- Your Level 2 LI and associated markup ]]
		<li class="menu-item mega-menu-title mega-menu-column [[+classnames]]"><a class="menu-link" href="[[+link]]" [[+attributes]]><div>[[+menutitle]]</div></a>[[+wrapper]]</li>
	`]]


	[[+level:is=`3`:then=`
		[[- Your Level 3 LI and associated markup ]]
		<li class="menu-item [[+classnames]]"><a class="menu-link" href="[[+link]]" [[+attributes]]><div>[[+menutitle]]</div></a>[[+wrapper]]</li>
	`]]


	[[+level:is=`4`:then=`
		[[- Your Level 4 LI and associated markup ]]
		<li class="menu-item [[+classnames]]"><a class="menu-link" href="[[+link]]" [[+attributes]]><div>[[+menutitle]]</div></a>[[+wrapper]]</li>
	`]]


`]]

A similar setup could be used in subMenuCintainerTpl to control the ULs and DIVs

1 Like

I think this is the way to go. I forgot there is now a level placeholder, it’s fairly new and doesn’t seem to be documented. @halftrainedharry is always good at looking under the hood!

1 Like

Hey dejaya…it’s my desired layout.

Do I do the level inside an id? Like you provided above? Is it possible to do that? I tried it and my nav had an error

[[+id:isnot=`8`

:then=`

	[[- Your default LI and associated markup for non-Competition pages ]]
	<li class="menu-item [[+classnames]]"><a class="menu-link" href="[[+link]]" [[+attributes]]><div>[[+menutitle]]</div></a>[[+wrapper]]</li>

`:else=`

	[[+level:is=`1`:then=`
		[[- Your Level 1 LI and associated markup ]]
		<li class="menu-item mega-menu [[+classnames]]"><a class="menu-link" href="[[+link]]" [[+attributes]]><div>[[+menutitle]]</div></a>[[+wrapper]]</li>
	`]]


	[[+level:is=`2`:then=`
		[[- Your Level 2 LI and associated markup ]]
		<li class="menu-item mega-menu-title mega-menu-column [[+classnames]]"><a class="menu-link" href="[[+link]]" [[+attributes]]><div>[[+menutitle]]</div></a>[[+wrapper]]</li>
	`]]


	[[+level:is=`3`:then=`
		[[- Your Level 3 LI and associated markup ]]
		<li class="menu-item [[+classnames]]"><a class="menu-link" href="[[+link]]" [[+attributes]]><div>[[+menutitle]]</div></a>[[+wrapper]]</li>
	`]]


	[[+level:is=`4`:then=`
		[[- Your Level 4 LI and associated markup ]]
		<li class="menu-item [[+classnames]]"><a class="menu-link" href="[[+link]]" [[+attributes]]><div>[[+menutitle]]</div></a>[[+wrapper]]</li>
	`]]


`]]

Hey @coconghaile

It definitely should be possible - my code was just an untested example really but it should be achievable.

What error do you see?

It is showing the [[+id:isnot=8:then= in the actual navigation bar.

That, I think, will be due to a bug in the 3.x MODX parser.

@halftrainedharry has posted a fix for that issue here.

However, even after applying that fix, I still see [what I think are] MODX tag parsing issues when adding output modifiers to the template chunks.

I still think it should be possible with pdoMenu but have hit a wall for now.

BTW - from my previous code …

[[+id:isnot=`8`

… isn’t quite right as we should be checking against the top-level parent of the current ID - not the ID itself.

Not sure I’ve helped much, sorry!