Ad

How To Get "leveltitle" For HMENU Items Via TypoScript?

- 1 answer

I have a menu (HMENU with special = updated) that gives me the latest sub and sub-sub pages from 3 categories. The page structure looks like this in the backend:

enter image description here

In addition to the title, I would like to output the name of the respective category (the parent level-1 page).

This is my TypoScript attempt:

lib.myMenu = HMENU
lib.myMenu {
    special = updated
    special{
        value.field = 10,11,12
        beginAtLevel = 1
        limit = 99
    }
    1 = TMENU
    1{
        NO{
            doNotLinkIt = 1
            stdWrap.cObject = COA
            stdWrap.cObject {
                10 = TEXT
                10{
                    wrap = <h3>|</h3>
                    field = seo_title // title
                    typolink.parameter.field = uid
                }

                20 = HMENU
                20{
                    wrap = <div class="category attempt-1">|</div>
                    special = rootline
                    special.range = 1|1
                    special.value.field = uid # does not work
                    1 = TMENU
                    1.NO.allWrap = |
                }

                30 = TEXT
                30{
                    wrap = <div class="category attempt-2">|</div>
                    data = leveltitle : 1 # does not work as expected
                }
            }
        }
    }
}

Unfortunately it does not work, because …

  1. special = rootline does not support special.value.
  2. data = leveltitle : 1 uses the ID of the current page, instead of the TMENU item ID.

Does anyone have another approach how I can get the title of the respective category using TypoScript?

Edit: Background information / what this is needed for

With this menu I intend to replace the news module ext:news of an existing project. Instead of news records, pages are now used and this menu creates the list view. Of course a TypoScript page browser will be added.

Ad

Answer

I have found a pure TypoScript solution that may not be very elegant, but it works:

lib.myMenu = HMENU
lib.myMenu {
    special = updated
    special{
        value.field = 10,11,12
        beginAtLevel = 1
        limit = 99
    }
    1 = TMENU
    1{
        NO{
            doNotLinkIt = 1
            stdWrap.cObject = COA
            stdWrap.cObject {
                10 = TEXT
                10{
                    wrap = <h3>|</h3>
                    field = seo_title // title
                    typolink.parameter.field = uid
                }

                20 = HMENU
                20{
                    wrap = <div class="category">|</div>
                    special = list
                    special.value.field = pid
                    1 = TMENU
                    1{
                        NO{
                            doNotLinkIt = 1
                            stdWrap.override{
                                # Overwrite it if we are not yet at the category level
                                if{
                                    # The ID of the page parent to the categories ("Website") is 1618
                                    equals = 1618
                                    value.field = pid
                                    negate = 1
                                }
                                cObject = HMENU
                                cObject{
                                    special = list
                                    special.value.field = pid
                                    1 = TMENU
                                    1.NO.doNotLinkIt = 1
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

If the menu is to go over further levels, the override must of course be nested even deeper.

Edit – Improvements:


RECORDS instead of HMENU: Bernd Wilke suggested in the comments to use CONTENT instead of HMENU to generate the category title. This caused problems in my tests when sysfolders (as subpages of the categories) were used to structure the items. This could be related to the bug/feature #20933 (Enable working with SysFolders in CONTENT). But RECORDS might be comparable. I tried it and was able to improve the render times a little bit (see table below).

lib.myMenu.1.NO.stdWrap.cObject.20 = RECORDS
lib.myMenu.1.NO.stdWrap.cObject.20{
    stdWrap.wrap = <div class="category">|</div>
    source.field = pid
    tables = pages
    conf.pages = TEXT
    conf.pages {
        field = seo_title // title
        stdWrap.override{
            # Overwrite it if we are not yet at the category level
            if{
                # The ID of the page parent to the categories ("Website") is 1618
                equals = 1618
                value.field = pid
                negate = 1
            }
            cObject = RECORDS
            cObject{
                source.field = pid
                tables = pages
                conf.pages = TEXT
                conf.pages.field = seo_title // title
            }
        }
    }
}

CONTENT instead of HMENU: if no sysfolders are needed (as of TYPO3 10.4 sysfolders should also work)

lib.myMenu.1.NO.stdWrap.cObject.20 = CONTENT
lib.myMenu.1.NO.stdWrap.cObject.20{
    stdWrap.wrap = <div class="category">|</div>
    table = pages
    select {
        uidInList.field = pid
        pidInList = 0
        selectFields = uid, pid, seo_title, title
    }
    renderObj = TEXT
    renderObj {
        field = seo_title // title
        stdWrap.override{
            # Overwrite it if we are not yet at the category level
            if{
                # The ID of the page parent to the categories ("Website") is 1618
                equals = 1618
                value.field = pid
                negate = 1
            }
            cObject = CONTENT
            cObject{
                table = pages
                select {
                    uidInList.field = pid
                    pidInList = 0
                    selectFields = uid, pid, seo_title, title
                }
                renderObj = TEXT
                renderObj.field = seo_title // title
            }
        }
    }
}

userFunc instead of HMENU: Bernd Wilke suggested in his answer to use a userfunction. Even if this is not a pure TypoScript solution, I would have liked to test it to be able to compare the performance. The method getRootLine() has unfortunately been marked as deprecated. Since I'm not an extension developer, it's not clear to me yet how to read the category via a userFunc and if this is actually more effective. If I still come across a solution regarding this, it will be added here.


Rendertime: I have test-implemented the menu in the live site (in the existing template) and compared the website render times with and without the output of the categories to see how much the nested menu affects the performance. The values are average values from 10 measurements. I also limited the output to 20 items, which should be a more realistic value per page later on:

mode20 items100 items
without category99 ms218 ms
categories via HMENU133 ms353 ms
categories via RECORDS132 ms331 ms
categories via CONTENT121 ms255 ms
categories via userFuncTBDTBD
Ad
source: stackoverflow.com
Ad