2
votes

Tearing my hair out over a TypoScript menu. I need the following behaviour:

  1. A list of "special" menu items pageIDs is maintained in constant {$SPECIAL}

  2. A HMENU is rendered showing the navigation of the site root. If the pageID is "special", then it gets a special div wrap, and a list of its child pages is nested inside of the div wrap. If the item is NOT "special", then it gets no special wrap, and no child pages are shown. All "special" items are shown at the top of the page list.

I've tried a couple of approaches:

Approach 1. Render two HMENUs, one after the other. First menu shows only {$SPECIAL}, second menu shows the siteroot, excluding the {$SPECIAL} items.

Problem: if I use special.directory to show {$SPECIAL}, the parent pages are not rendered. If I use special.list, the child pages are not rendered. Argh!

Approach 2. Render a big chunk of custom menu TS, using if conditions to check if the page is {$SPECIAL}

Problem: I can get the special wraps to show on {$SPECIAL} items, but I can't work out how to then render a list of the child pages specific to each item.

My code for Approach 2 is, so far:

    MAIN_NAV.20 = HMENU
    MAIN_NAV.20 {
      special = directory
      special.value = {$SITE_ROOT}
      excludeUidList = {$RESTRICTED_ROOT}, {$HOME_SHORTCUT}

      1 = TMENU
      1{
       NO{
         # suppress standard menu output
         doNotShowLink = 1

         # build each menu item conditionally
         stdWrap2.cObject = COA
         stdWrap2.cObject{

         #Standard
         10 = TEXT
         10{
           # not in list of special pages?
           if.value = {$NAV_CONTAINERS}
           if.isInList.field = uid
           if.negate = 1

           field = nav_title//title
           typolink.parameter.field = uid
           wrap = <ul><li>|</li></ul>
         }

         #Special
         20 = TEXT
         20.wrap = <div class="SPECIAL"><ul><li><span>|</span>
         20 {
            if.value.field = uid
            if.equals = {$SPECIAL}

            field = nav_title//title

          }

          30 = TEXT
          30.wrap = |</li></ul></div>
          30 {
                  if.value.field = uid
                  if.equals = {$SPECIAL}
          }

          }
        }
      }
    }

I can't hardcode this (like "Special item 1 as a text element, then Special item 1 children as a menu, then Special item 1 as a text element, then Special item 2 children...") because {$SPECIAL} could theoretically wind up being any number of pages.

Can anyone offer any suggestions to assist with one or other approach?

1
in order to render the child pages in a HMENU you need to define the 2nd level according to the 1st level. something like "2 = TMENU"Kitze

1 Answers

1
votes

I think user Ila is right, if you use special = list, you should be able to add multiple levels (child pages) by adding TMENUs.

On the other hand, I've got a similar menu I'd like to share. It contains two kinds of special rendering cases - one with override.if and the other one with CASE.

temp.mainnav = HMENU
temp.mainnav {
  wrap = <nav>|</nav>
  entryLevel = 0

  1 = TMENU
  1 {
        noBlur = 1
        expAll = 1
        wrap = <ul>|</ul>
        NO {
            wrapItemAndSub=<li class="p{page:uid}">|</li>   
            wrapItemAndSub.insertData = 1               
        }
    }

    2 = TMENU
    2   {
        noBlur = 1
        expAll = 1
        NO {
            wrapItemAndSub=<li>|</li>       
            // http://labor.99grad.de/2013/07/10/typo3-hmenu-einen-menupunkt-anders-darstellen/
            doNotLinkIt.override = 1
            doNotLinkIt.override.if {
               value = {$pidsDoNotLinkInMenu}
               isInList.field = uid
            }
            stdWrap.wrap.override = <p class="unlinkedMenuItem">|</p>
            stdWrap.wrap.override.if {
               value = {$pidsDoNotLinkInMenu}
               isInList.field = uid
            }
        }
    }


    3 = TMENU
    3 {
        noBlur = 1
        expAll = 1
        wrap = <ul class="level3">|</ul>

        NO.wrapItemAndSub.cObject = CASE
        NO.wrapItemAndSub.cObject  {
        //http://stackoverflow.com/questions/18899573/how-to-apply-a-different-wrap-in-a-tmenu-for-certain-items-only/18910302?noredirect=1#18910302

            key.field = uid                

            // normal item
            default = TEXT
            default.value =  <li class="level3">|</li>     

            // special item 
            {$somePid} = TEXT
            {$somePid}.value = <li class="level3 foo">|</li>
            {$somePid}.append < temp.sometemp

            // some other special item
            {$someOtherpid} = TEXT
            {$someOtherpid}.value = <li class="level3 bar">|</li>
            {$someOtherpid}.append < temp.someothertemp

        }
    }

}

I think both approaches could be used to achieve your goal.