PHPackages                             b13/menus - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. b13/menus

ActiveTypo3-cms-extension[Utility &amp; Helpers](/categories/utility)

b13/menus
=========

Easy and fast menus for TYPO3 Frontends

1.1.3(6mo ago)58534.7k↓14.2%24[3 issues](https://github.com/b13/menus/issues)[1 PRs](https://github.com/b13/menus/pulls)1GPL-2.0-or-laterPHPCI passing

Since Nov 25Pushed 4mo ago15 watchersCompare

[ Source](https://github.com/b13/menus)[ Packagist](https://packagist.org/packages/b13/menus)[ RSS](/packages/b13-menus/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (9)Versions (25)Used By (1)

[![CI](https://github.com/b13/menus/actions/workflows/ci.yml/badge.svg)](https://github.com/b13/menus/actions/workflows/ci.yml/badge.svg)

Menus - A TYPO3 Extension for creating fast menus - in a fast way
=================================================================

[](#menus---a-typo3-extension-for-creating-fast-menus---in-a-fast-way)

Introduction
------------

[](#introduction)

TYPO3 CMS is known for handling large websites with lots of content. TYPO3 Core provides several ways to build navigation / menus in a very flexible way. However, generating menus has been a tedious issue in most of our large-scale projects. With TYPO3 v9, the performance of generating menus improved when it comes to URL generation, but a few conceptual issues within linking and menu generation still exist:

1. All logic relies on HMENU

    Every menu is generated using HMENU, even the MenuDataProcessor for Fluid is using this. Yes, it's powerful, but also offers a lot of options we do not need in most circumstances.
2. HMENU saves states for each page

    HMENU offers the possibility to define A LOT of states ("active", "current", "has children"). This information is different for each page - obviously - which is then cached in a separate cache entry in `cache_hash` - making the cache entries fairly large even though we do not use states.

    We use `expAll` (expand all subpages for all other pages as well) which makes the requests to the pages enormously large.
3. HMENU has a cryptic syntax for "special" menus

    Nowadays, it is fairly common to build menus for footer navigation, mega-menus, sitemap-like menus for an additional sidebar. Using "special." for language menus, for "directories" or just a simple list of pages, seems rather complex.

This extension tries to overcome these pitfalls by

- building menus once, then caches the results and afterwards applying active states (reduce amount of cached data). This is especially important for Tree-based menus,
- introducing new cObjects and DataProcessors for the specific use cases making them more understandable for non-TYPO3-Gurus.

Installation &amp; Requirements
-------------------------------

[](#installation--requirements)

Use `composer req b13/menus` or install it via TYPO3's Extension Manager from the [TYPO3 Extension Repository](https://extensions.typo3.org) using the extension key `menus`.

You need TYPO3 v9 with Site Handling for this extension to work. If your project supports mount points, this is not implemented. In addition, pages to access restricted pages (even though no access exists) are not yet considered.

Features
--------

[](#features)

The extension ships TypoScript cObjects and TypoScript DataProcessors for Fluid-based page templates.

### Common Options for all menus

[](#common-options-for-all-menus)

- excludePages - a list of page IDs (and their subpages if Tree Menu or Breadcrumbs is used) to exclude from the page
- excludeDoktypes - a list of doktypes that are not rendered. BE\_USER\_SECTIONs are excluded by default. SYS\_FOLDERs are queried (for subpages etc) but never rendered.
- includeNotInMenu - include pages with nav\_hide set to 1, instead of ignoring them

### Common options for items

[](#common-options-for-items)

In TypoScript this is available as `field:isSpacer`, in Fluid, this is accessible in `{page.isSpacer}`

```
- {page.isCurrentPage} (bool)
- {page.isInRootLine} (bool)
- {page.isSpacer} (bool)
- {page.hasSubpages} (bool) - TreeMenu only
- {page.subpages} (array) - TreeMenu only

```

### Tree Menu

[](#tree-menu)

Use this for mega menus, or separate menus for mobile devices, like sitemaps.

Pure TypoScript-based solution:

```
page.10 = TREEMENU
# a list of page IDs, rootpageID is used if none given
page.10.entryPoints = 23,13
# the number of levels to fetch from the database (1 if empty)
page.10.depth = 3
page.10.excludePages = 4,51
# 0: default, 1 to include nav_hide = 1 pages
page.10.includeNotInMenu = 0
page.10.renderObj.level0 = TEXT
page.10.renderObj.level0.typolink.parameter.data = field:uid
page.10.renderObj.level0.typolink.ATagParams = class="active"
page.10.renderObj.level0.typolink.ATagParams.if.isTrue.field = isInRootLine
page.10.renderObj.level0.dataWrap = |{field:subpageContent}

```

Fluid-based solution:

```
page.10 = FLUIDTEMPLATE
page.10.dataProcessing.10 = B13\Menus\DataProcessing\TreeMenu
page.10.dataProcessing.10.entryPoints = 23,13
page.10.dataProcessing.10.depth = 3
page.10.dataProcessing.10.excludePages = 4,51
# 0: default, 1 to include nav_hide = 1 pages
page.10.dataProcessing.10.includeNotInMenu = 0
page.10.dataProcessing.10.as = mobilemenu

```

Usage in Fluid:

```

        {page.nav_title}

                    {subpage.nav_title}

```

**Note**: nav\_title is title if Database-Record nav\_title is empty.

### Language Menu

[](#language-menu)

Building a language switcher can be achieved by a few lines of code:

Pure TypoScript solution:

```
page.10 = LANGUAGEMENU
page.10.excludeLanguages = de,en
# 0: default, 1 to include nav_hide = 1 pages
page.10.includeNotInMenu = 0
# add all siteLanguages to menu even if page is not available in language (default 0)
page.10.addAllSiteLanguages = 1
page.10.wrap =  |
page.10.renderObj.typolink.parameter.data = field:uid
page.10.renderObj.typolink.additionalParams.data = field:language|languageId
page.10.renderObj.typolink.additionalParams.intval = 1
page.10.renderObj.typolink.additionalParams.wrap = &L=|
page.10.renderObj.data = field:language|title // field:language|twoLetterIsoCode
page.10.renderObj.wrap =  |

```

The stdWrap `data` is the information of the current page plus the information merged from the selected SiteLanguage.

Fluid-based solution:

```
page.10 = FLUIDTEMPLATE
page.10.dataProcessing.10 = B13\Menus\DataProcessing\LanguageMenu
page.10.dataProcessing.10.excludeLanguages = de,en
# 0: default, 1 to include nav_hide = 1 pages
page.10.dataProcessing.10.includeNotInMenu = 0
# add all siteLanguages to menu even if page is not available in language (default 0)
page.10.dataProcessing.10.addAllSiteLanguages = 1
page.10.dataProcessing.10.as = languageswitcher

```

Usage in Fluid:

```

        {item.language.title}

```

**Note**: the languageMenu hold the siteLanguage on each item in the `language` property as an array

### List Menu

[](#list-menu)

If you just want a list of all items within a folder, or for a link list in the footer, use the List Menu.

Pure TypoScript-based solution:

```
page.10 = LISTMENU
# a page ID, rootpageID is used if none given, stdWrap possible
page.10.pages = 13,14,15
# 0: default, 1 to include nav_hide = 1 pages
page.10.includeNotInMenu = 0
page.10.wrap =  |
page.10.renderObj = TEXT
page.10.renderObj.typolink.parameter.data = field:uid
page.10.renderObj.wrap =  |

```

Fluid-based solution:

```
page.10 = FLUIDTEMPLATE
page.10.dataProcessing.10 = B13\Menus\DataProcessing\ListMenu
page.10.dataProcessing.10.pages = 13,14,15
page.10.dataProcessing.10.as = footerlinks
# 0: default, 1 to include nav_hide = 1 pages
page.10.dataProcessing.10.includeNotInMenu = 0

```

Usage in Fluid:

```

        {page.nav_title}

```

### Breadcrumb Menu (a.k.a. Rootline Menu)

[](#breadcrumb-menu-aka-rootline-menu)

```
page.10 = BREADCRUMBS
page.10.excludePages = 4,51
# 0: default, 1 to include nav_hide = 1 pages
page.10.includeNotInMenu = 0
page.10.wrap =  |
page.10.renderObj = TEXT
page.10.renderObj.typolink.parameter.data = field:uid
page.10.renderObj.wrap =  |

```

Fluid-based solution:

```
page.10 = FLUIDTEMPLATE
page.10.dataProcessing.10 = B13\Menus\DataProcessing\BreadcrumbsMenu
page.10.dataProcessing.10.excludePages = 4,51
# 0: default, 1 to include nav_hide = 1 pages
page.10.dataProcessing.10.includeNotInMenu = 0
page.10.dataProcessing.10.as = breadcrumbs

```

Usage in Fluid:

```

        {page.nav_title}
         &nbsp;

```

### Dynamic configuration values for the menu (stdWrap)

[](#dynamic-configuration-values-for-the-menu-stdwrap)

If you want to get a menu of the direct siblings of a page, no matter what page you have selected, you can use the stdWrap functions built into each property:

```
9999 = B13\Menus\DataProcessing\TreeMenu
9999 {
	entryPoints.data = page:pid
	as = listOfJobPages
}

```

By using the `.data` property of the `entryPoints` attribute we can access each property of the currently build page. And so we can render the siblings of the page.

Technical Details
-----------------

[](#technical-details)

### Caching

[](#caching)

Fetching the records is cached in a cache entry (with proper cache tags) within "cache\_hash", and the rendering is also cached in a separated cache entry within "cache\_pages" for each page (regular), where active state is applied.

### FAQ

[](#faq)

This extension refrains from handling options `addQueryParams`, or `ADD_GET_PARAM`, or the `target` property in order to deal with the pages as "native" as possible, like any other link.

License
-------

[](#license)

The extension is licensed under GPL v2+, same as the TYPO3 Core. For details see the LICENSE file in this repository.

Open Issues
-----------

[](#open-issues)

If you find an issue, feel free to create an issue on GitHub or a pull request.

### ToDos

[](#todos)

- add `includeSpacer` option
- extract stdWrap functionality out of caching parameters

### Credits

[](#credits)

This extension was created by [Benni Mack](https://github.com/bmack) in 2019 for [b13 GmbH](https://b13.com).

[Find more TYPO3 extensions we have developed](https://b13.com/useful-typo3-extensions-from-b13-to-you) that help us deliver value in client projects. As part of the way we work, we focus on testing and best practices to ensure long-term performance, reliability, and results in all our code.

###  Health Score

58

—

FairBetter than 98% of packages

Maintenance72

Regular maintenance activity

Popularity52

Moderate usage in the ecosystem

Community31

Small or concentrated contributor base

Maturity67

Established project with proven stability

 Bus Factor2

2 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~155 days

Recently: every ~205 days

Total

15

Last Release

193d ago

Major Versions

0.5.1 → 1.0.02022-11-29

PHP version history (3 changes)v0.1.0PHP ^7.2

v0.3.0PHP ^7.2 || ~8.0

1.0.0PHP ^7.4 || ~8.0

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/165630?v=4)[Benni Mack](/maintainers/bmack)[@bmack](https://github.com/bmack)

![](https://avatars.githubusercontent.com/u/2851821?v=4)[b13 GmbH](/maintainers/b13)[@b13](https://github.com/b13)

---

Top Contributors

[![bmack](https://avatars.githubusercontent.com/u/165630?v=4)](https://github.com/bmack "bmack (60 commits)")[![achimfritz](https://avatars.githubusercontent.com/u/2152991?v=4)](https://github.com/achimfritz "achimfritz (35 commits)")[![ervaude](https://avatars.githubusercontent.com/u/7824856?v=4)](https://github.com/ervaude "ervaude (7 commits)")[![georgringer](https://avatars.githubusercontent.com/u/1905663?v=4)](https://github.com/georgringer "georgringer (6 commits)")[![davidsteeb](https://avatars.githubusercontent.com/u/3862523?v=4)](https://github.com/davidsteeb "davidsteeb (4 commits)")[![sbuerk](https://avatars.githubusercontent.com/u/1453466?v=4)](https://github.com/sbuerk "sbuerk (3 commits)")[![b13-michaelsemle](https://avatars.githubusercontent.com/u/23473071?v=4)](https://github.com/b13-michaelsemle "b13-michaelsemle (3 commits)")[![infabo](https://avatars.githubusercontent.com/u/3999104?v=4)](https://github.com/infabo "infabo (3 commits)")[![simonschaufi](https://avatars.githubusercontent.com/u/941794?v=4)](https://github.com/simonschaufi "simonschaufi (2 commits)")[![lochmueller](https://avatars.githubusercontent.com/u/3907126?v=4)](https://github.com/lochmueller "lochmueller (2 commits)")[![neufeind](https://avatars.githubusercontent.com/u/910025?v=4)](https://github.com/neufeind "neufeind (2 commits)")[![RTPAst](https://avatars.githubusercontent.com/u/77045250?v=4)](https://github.com/RTPAst "RTPAst (2 commits)")[![julianhofmann](https://avatars.githubusercontent.com/u/25646388?v=4)](https://github.com/julianhofmann "julianhofmann (1 commits)")[![kaystrobach](https://avatars.githubusercontent.com/u/1185776?v=4)](https://github.com/kaystrobach "kaystrobach (1 commits)")[![linawolf](https://avatars.githubusercontent.com/u/48202465?v=4)](https://github.com/linawolf "linawolf (1 commits)")[![runepiper](https://avatars.githubusercontent.com/u/4521147?v=4)](https://github.com/runepiper "runepiper (1 commits)")[![magicHatOfTYPO3](https://avatars.githubusercontent.com/u/12638829?v=4)](https://github.com/magicHatOfTYPO3 "magicHatOfTYPO3 (1 commits)")[![chesio](https://avatars.githubusercontent.com/u/2021167?v=4)](https://github.com/chesio "chesio (1 commits)")[![achimfritz-b13](https://avatars.githubusercontent.com/u/156071319?v=4)](https://github.com/achimfritz-b13 "achimfritz-b13 (1 commits)")[![jdreesen](https://avatars.githubusercontent.com/u/424602?v=4)](https://github.com/jdreesen "jdreesen (1 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/b13-menus/health.svg)

```
[![Health](https://phpackages.com/badges/b13-menus/health.svg)](https://phpackages.com/packages/b13-menus)
```

###  Alternatives

[fluidtypo3/flux

The flux package from FluidTYPO3

152982.2k20](/packages/fluidtypo3-flux)[friendsoftypo3/content-blocks

TYPO3 CMS Content Blocks - Content Types API | Define reusable components via YAML

96374.6k23](/packages/friendsoftypo3-content-blocks)[brotkrueml/schema

Embedding schema.org vocabulary - API and view helpers for schema.org markup

33584.6k13](/packages/brotkrueml-schema)[eliashaeussler/typo3-form-consent

Extension for TYPO3 CMS that adds double opt-in functionality to EXT:form

1481.0k](/packages/eliashaeussler-typo3-form-consent)[b13/assetcollector

Add CSS and SVG files and strings as inline style tag/inline svg to the html code.

10118.4k](/packages/b13-assetcollector)[mautic/mautic-typo3

Add-on TYPO3 extension that enhances the "EXT:marketing\_automation" TYPO3 extension by connecting it to the Mautic Marketing Automation platform: Determine "Persona" from Mautic segments. Also provides additional services e.g. language synchronisation between Mautic and TYPO3.

236.3k](/packages/mautic-mautic-typo3)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
