Search code examples
masktyposcripttypo3-9.x

How to create a HMENU/TMENU with Icons that came from a Mask field (text)?


With the extension "Mask" I've added some fields in Page Templates to assign Icons to pages. Also you can use a checkbox to activate the selected icon in menus. Menu meaning this case: I've also made a Content Element with Mask where you only enter a UID and all subpages of that UID will be created as <li> list.

I've set up the following fields in Page Templates:

  • page_01_icon (String): will contain something like "icon-home"
  • page_02_color (String): this will be the color of the icon or the background-color for the list element; depends on `page_color_background`, valid values are any css hex colors like "#a5011c"
  • page_02_color_text (String): if set, the text color will be changed to this
  • page_03_menu (Checkbox): checked == `page_icon` will be shown; else only the title of the page
  • page_04_icon_only_menu (Checkbox): checked == only icon will be shown, title not (not needed for my question, I use this only in the main menu)
  • page_05_color_background (Checkbox): if checked `page_color` is used as background color for this list element, if not the icon will get the colored with `page_color`; if `page_color` is not set at all neither icon or the background will get an color

I am very new to Typo3, but I actually get the above code work with the normal header menu on my page. It was a hard way there but that part works. For the header menu I could do it in FLUID, but this is now a lib and I need to do the same here but with TypoScript - no matter what I try I coudn't get it right. Most examples and how-tos rely on "if uid = 1..25" do something else. But I need multiple if elses for this. I think how I've done in FLUID is the right way, now trying to get the same logic to TypoScript... and ended up here.

Page Template Fields in Mask
This is how I added the fields in Mask

Content-Fields
Pages -> Edit -> Content-Fields (of Mask-Fields)

Main Menu Bar
This is what I've done with FLUID (the main menu bar). Icon-only + Icon and Title + Title only.

Spoken in simple PHP logic I would do the following (just to explain the main thinking / way I try in TypoScript):

    // dont need to check if page_01_icon is set: field is required
    // dont need to check if page_03_menu is checked: icons in this typo3 lib will always be displayed
    // just assume that $title holds the title and $url the url to that page

    foreach(....) {
      // save html/css code in var for text color if a color is set
      if(isset($page_02_color_text)) {
        $textColorHTML = ' style="color' . $page_02_color_text . '"';
      } else {
        $textColorHTML = '';
      }

      // save html/css code in background of <li> if background-checkbox is checked and a color is set
      if ($page_05_color_background == 1 && isset(page_02_color)) {
        $liBackgroundHTML = ' style="background-color:' . $page_05_color_background . '"';
      } else {
        $liBackgroundHTML = '';
      }

      echo '<li' . $liBackgroundHTML . '><a href="' . $url . '" ' . $textColorHTML . '><i class="' . $page_01_icon . '"></i> ' . $title . </a></li>';
    }

Basicly thats what I tryied to try in TypoScript :)

What I "have":
A Mask template-file with the following content:

<f:cObject typoscriptObjectPath="lib.linkListAuto" data="{data}" />

The lib.linkListAuto-file:
This is the default version without the php logic from above. here I need to "translate" the php logic into.. I couldn't even post a half way woring script cuz everything I#ve tried ended as the wrong way :/

lib.linkListAuto = COA
lib.linkListAuto {
    1 = HMENU
    1 {
        special = directory
        special.value.field = tx_mask_link_root_id

        wrap = <ul class="list-group">|</ul>
        stdWrap.if.isTrue.data = register:count_menuItems

        1 = TMENU
        1 {
            NO = 1
            NO {
                allWrap = <li class="list-group-item">|</li>
                stdWrap.htmlSpecialChars = 1
                ATagTitle.field = description // subtitle // title
            }
        }
    }
}

How can I say in TypoScript "render this way every link (sub-page) that comes",
but if a color ist set and the checkbox for use_color_as_background ist checked: change the rendering for this entry and give the <li> a background-color
also change the text color if it is set
and finaly add the icon in front of the page-title
?

Please help with ideas that dont come up with "if uid equals X"-examples. Had enough of them, they work, yes, but I cant change them to what I am trying to do.


Solution

  • You need to understand the concept of TypoScript.
    So the name may be misleading. TypoScript is not a scripting language but a configuration language. So you can't use the concept of a sequential computation.

    In this way you configure your rendering.

    Anyway you can add some logic to the rendering in the form of the .stdWrap.if function which can control whether a value is printed in the output.

    The other important functionality is string concatenation: in TypoScript you can use COAs (Content Object Array) to build up a string where you decide for each array element how it is displayed.

    For building up the string <li' . $liBackgroundHTML . '><a href="' . $url . '" ' . $textColorHTML . '><i class="' . $page_01_icon . '"></i> ' . $title . </a></li> you might use something like:

    temp.li_tag = COA
    temp.li_tag {
        10 = TEXT
        10.value = <li
    
        // if ($page_05_color_background == 1 && isset(page_02_color)) {
        //   $liBackgroundHTML = ' style="background-color:' . $page_05_color_background . '"';
        // } else {
        //   $liBackgroundHTML = '';
        // }
        20 = TEXT
        20.field = page_05_color_background
        20.noTrimWrap = | style="background-color:|"|
        20.if.isTrue.field = page_02_color
    
        30 = TEXT
        30.value = ><a href="
    
        40 = TEXT
        40.field = title
        40.dataWrap = <i class="{field.page_01_icon}"></i>&nbsp;|
        40.stdWrap.typolink {
           parameter.field = uid
    
           // if(isset($page_02_color_text)) {
           //   $textColorHTML = ' style="color' . $page_02_color_text . '"';
           // } else {
           //   $textColorHTML = '';
           // }
           ATagParams.cObject = TEXT
           ATagParams.cObject {
             field = page_02_color_text
             wrap = style="color|"
             if.isTrue.field = page_02_color_text
           } 
        }
    
        50 = TEXT
        50.value = </li>
    }