Installation:
composer require nucleos/menu-bundle
Enable the bundle in config/bundles.php:
return [
// ...
Nucleos\MenuBundle\NucleosMenuBundle::class => ['all' => true],
];
First Use Case:
Define a menu in YAML (e.g., config/menus/main.yaml):
main:
label: 'Main Menu'
items:
- label: 'Home'
uri: '/'
icon: 'fas fa-home'
- label: 'About'
uri: '/about'
Register the menu in config/packages/nucleos_menu.yaml:
nucleos_menu:
menus:
main: '@main'
Render in Twig:
{{ render_menu('main') }}
YAML Configuration:
config/menus/*.yaml for static menus (e.g., main.yaml, admin.yaml).@filename syntax in nucleos_menu.yaml.Dynamic Menus via Services:
MenuBuilder to fetch menus from a database or API:
// src/Service/CustomMenuBuilder.php
use Nucleos\MenuBundle\Menu\MenuBuilderInterface;
class CustomMenuBuilder implements MenuBuilderInterface {
public function build(string $name): array {
return $this->fetchFromDatabase($name);
}
}
services.yaml:
services:
Nucleos\MenuBundle\Menu\MenuBuilderInterface: '@custom_menu_builder'
Nested Menus:
# config/menus/admin.yaml
admin:
label: 'Admin Panel'
items:
- label: 'Users'
uri: '/admin/users'
children:
- label: 'List'
uri: '/admin/users/list'
- label: 'Create'
uri: '/admin/users/create'
Conditional Items: Use Twig logic in templates or PHP callbacks in YAML:
items:
- label: 'Dashboard'
uri: '/dashboard'
visible: '@=user.hasRole("ROLE_ADMIN")'
Twig Extensions:
Override render_menu in Twig to customize output:
{% macro render_menu(menu, options={}) %}
<nav class="custom-menu">
{% for item in menu.items %}
<a href="{{ item.uri }}">{{ item.label }}</a>
{% endfor %}
</nav>
{% endmacro %}
Event Listeners:
Modify menus dynamically via MenuEvents:
// src/EventListener/MenuListener.php
use Nucleos\MenuBundle\Event\MenuEvent;
class MenuListener {
public function onBuildMenu(MenuEvent $event) {
$event->getMenu()->addItem('custom_item', [
'label' => 'Dynamic Item',
'uri' => '/dynamic',
]);
}
}
Register in services.yaml:
services:
App\EventListener\MenuListener:
tags:
- { name: 'kernel.event_listener', event: 'nucleos_menu.build', method: 'onBuildMenu' }
Caching Issues:
php bin/console cache:clear
nucleos_menu.yaml for development:
nucleos_menu:
cache: false
YAML Syntax Errors:
symfony/validator or use an online validator.:), incorrect indentation, or undefined references (@filename).Overwriting Defaults:
main or admin to prevent conflicts with future updates.Twig Template Overrides:
nucleos_menu.html.twig if customizing:
{% extends 'nucleos_menu.html.twig' %}
{% block menu_item %}
<li class="custom-class">{{ item.label }}</li>
{% endblock %}
dump to inspect the menu array:
{{ dump(render_menu('main')) }}
Menu tab for built menus and their metadata.Custom Menu Builders:
Implement MenuBuilderInterface for non-YAML sources (e.g., Doctrine entities):
class DoctrineMenuBuilder implements MenuBuilderInterface {
public function build(string $name): array {
return $this->entityManager->getRepository(MenuEntity::class)
->findBy(['name' => $name]);
}
}
Menu Item Transformers:
Use MenuItemTransformerInterface to modify items post-build:
class UrlTransformer implements MenuItemTransformerInterface {
public function transform(array $item): array {
$item['uri'] = route($item['route'], [], $item['route_params']);
return $item;
}
}
Register in services.yaml:
services:
App\Transformer\UrlTransformer:
tags:
- { name: 'nucleos_menu.item_transformer' }
Localization: Use Symfony’s translation system for labels:
items:
- label: '@trans("menu.home")'
uri: '/'
Define translations in translations/messages.en.yaml:
menu:
home: 'Home'
How can I help you explore Laravel packages today?