phil / menu-bundle
Menus for Symfony: trees of items built in code, decorated by the application — counts, classes, badges —, their current item and ancestors marked from the request, a breadcrumb, and lists or cards in Twig
Package info
github.com/parler-haut-interagir-librement/menu-bundle
Type:symfony-bundle
pkg:composer/phil/menu-bundle
Requires
- php: >=8.5
- ext-mbstring: *
- symfony/dependency-injection: ^8.2
- symfony/http-foundation: ^8.2
Requires (Dev)
- phpunit/phpunit: ^13.4
- psr/log: ^3.0
- symfony/config: ^8.2
- symfony/event-dispatcher: ^8.2
- symfony/framework-bundle: ^8.2
- symfony/http-kernel: ^8.2
- symfony/routing: ^8.2
- symfony/translation: ^8.2
- symfony/translation-contracts: ^3.6
- symfony/twig-bridge: ^8.2
- symfony/twig-bundle: ^8.2
- twig/twig: ^3.21
Suggests
- symfony/routing: For the routes of items in the templates, and their absolute URLs in menu_breadcrumb_schema
- symfony/translation-contracts: For the labels translated in menu_breadcrumb_schema, as the templates translate them
- twig/twig: For menu, menu_breadcrumb, menu_breadcrumb_schema and the templates
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-11-11 13:31:09 UTC
README
Navigation menus and breadcrumbs for Symfony, with the visitor's current page marked.
phil/menu-bundle builds menus as trees of immutable items. Each item has a key, a label, a route or a URL, and may
carry an icon, a description, counts, classes and attributes. The bundle marks the item the visitor is on and the
items that lead to it, from the request's route or path. Twig shows a menu as a navigation list, as cards or as a
breadcrumb, and gives the breadcrumb as a schema.org BreadcrumbList. It does not store menus: a builder reads them
from wherever the application keeps them. It does not count anything either, since counting is a decorator's work.
It is for Symfony applications whose navigation is more than a few fixed links: sections with counts of their
entries, cards whose attributes a script sorts or filters in the browser, a breadcrumb on every page. The templates
mark the current link with aria-current="page" for screen readers.
The design rests on two extension points, found by autoconfiguration. A MenuBuilder makes one menu from code, a
table or a file. MenuDecorator services then change its items in order of priority, children before their parent,
to add counts, badges, classes or children from elsewhere. Twig is optional: without it, Menus still gives each
menu built, decorated and marked.
Status
| Part | State |
|---|---|
MenuItem and Menu: immutable trees, keys, counts, attributes, breadcrumb |
Implemented and tested |
MenuBuilder, MenuDecorator, found by autoconfiguration; Menus |
Implemented and tested |
| The current item and its ancestors, from the route or the path | Implemented and tested |
Twig: menu, menu_breadcrumb, menu_breadcrumb_schema; list, cards and breadcrumb templates |
Implemented and tested |
Documentation
| Document | What it covers |
|---|---|
| Installation | Requirements and registering. |
| Items and menus | MenuItem, Menu, and what an item holds. |
| Builders and decorators | Making a menu, changing it, in which order. |
| The current item | How the current item and its ancestors are told. |
| Twig | The functions and the three templates. |
| Testing | How the bundle is tested. |
| Reference | Every type of the bundle. |
Quick start
composer require phil/menu-bundle
final class MainMenu implements MenuBuilder { public function name(): string { return 'main'; } public function build(MenuContext $context): Menu { return Menu::of('main', [ MenuItem::of('home', 'Home')->withRoute('home'), MenuItem::of('games', 'Games')->withRoute('games')->withChildren( MenuItem::of('chess', 'Chess')->withRoute('game', ['slug' => 'chess']), ), ]); } }
{% include '@PhilMenu/menu.html.twig' with {menu: menu('main')} %}
Requirements
PHP 8.5 or later with ext-mbstring; symfony/dependency-injection and symfony/http-foundation 8.2 or later.
Twig is optional; the templates use the router's path().
Contributing
Contributions are welcome on the PHIL monorepo: read the contribution guide and the code of conduct. Report a vulnerability privately, as the security policy explains, never in a public issue.
License
MIT, © Philippe Gamache, doing business as Le Gnome Archiviste; a Parler Haut Interagir Librement project. See LICENSE.