Rendering menus in TYPO3

There are several strategies to display menus or other navigation elements like breadcrumbs and sitemaps in TYPO3.

TypoScrip configuration of the main menu

We use TypoScript to configure these menus. The main menu is configured like this:

packages/my_site_package/Configuration/Sets/SitePackage/TypoScript/Navigation/menu.typoscript
page {
  10 {
    dataProcessing {
      20 = menu
    }
  }
}
Copied!

This menu defines that the variable with the default name menu should contain the information about the complete page tree of the current page.

System folders like the "Footer menu" from your example data, special page types and pages excluded from the navigation are excluded.

A complete reference of this menu can be found in the TypoScript Reference: menu data processor.

Fluid partial of the main menu

In packages/my_site_package/Resources/Private/PageView/Partials/Navigation/Menu.html you can find the partial that renders the main menu.

A menu usually contains several menu entries. We use the For ViewHelper <f:for> to iterate over all menu entries and render them in turn:

packages/my_site_package/Resources/Private/PageView/Partials/Navigation/Menu.html
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
    <f:for each="{menu}" as="menuItem">
        <li class="nav-item">
            <a class="nav-link {f:if(condition: menuItem.active, then:'active')}"
               href="{menuItem.link}"
               target="{menuItem.target}"
               title="{menuItem.title}"
            >
                {menuItem.title}
            </a>
        </li>
    </f:for>
</ul>
Copied!

In each loop the current menu item is stored in variable {menuItem}.

You can use the Debug ViewHelper <f:debug> to debug what kind of data the variable contains like this:

packages/my_site_package/Resources/Private/PageView/Partials/Navigation/Menu.html (changed for debug output)
<ul class="navbar-nav mr-auto">
    <f:for each="{menu}" as="menuItem">
+       <f:debug>{menuItem}</f:debug>
        <li class="nav-item {f:if(condition: menuItem.active, then:'active')}">
Copied!

The debug output on your page should now look like this:

array(8 items)
    data => array(78 items)
    title => 'My page' (22 chars)
    link => '/my-page' (26 chars)
    target => '' (0 chars)
    active => 0 (integer)
    current => 0 (integer)
    spacer => 0 (integer)
    hasSubpages => 1 (integer)
Copied!

The following data is of interest:

{menuItem.data}:
Contains the raw data of the database record of the page for the menu item.
{menuItem.link}:
The actual link to the page. For external links it contains the URL.
{menuItem.target}:
This might contain "_blank" if the menu item represents an external link.
{menuItem.title}:
The title to be displayed in the menu. By default the navigation title if set, the title otherwise.
{menuItem.active}
Contains 1 if the page of the current menu item is in the rootline of the current page.

The construct {f:if(condition: menuItem.active, then: 'active')} output the string "active" if {menuItem.active} is set. The syntax might look confusing at first. It is an If ViewHelper <f:if> displayed in the Fluid inline notation.

Preview the page and use the menu

Whenever you change TypoScript files or Fluid templates, flush all caches:

ddev typo3 cache:flush
Copied!
Checking from the backend if the menu is generated as expected.

Checking from the backend if the menu is generated as expected.

Different menu types

We use the menu data processor to demonstrate different menu types:

  • A breadcrumb configured in packages/my_site_package/Configuration/Sets/SitePackage/TypoScript/Navigation/breadcrumb.typoscript and rendered in packages/my_site_package/Resources/Private/PageView/Partials/Navigation/Breadcrumb.html.
  • A footer menu (example is still missing).