Installation:
composer require desarrolla2/menu-bundle
Verify composer.json includes the package under require.
Enable the Bundle:
Add to AppKernel.php:
new Desarrolla2\MenuBundle\Desarrolla2MenuBundle(),
(Note: The README incorrectly references Knp\Bundle\Desarrolla2\MenuBundle—use the correct namespace.)
First Menu:
Create a builder class (e.g., src/AdminBundle/Menu/MainMenu.php):
namespace AdminBundle\Menu;
use Desarrolla2\MenuBundle\Menu\MenuInterface;
class MainMenu implements MenuInterface {
public function getMenu() {
return [
'class' => 'main-menu',
'items' => [
['name' => 'Home', 'route' => 'homepage'],
],
];
}
}
Register the Menu:
Add to services.yml (or config/services.yaml in Symfony 4+):
servicios.menu.main:
class: AdminBundle\Menu\MainMenu
tags:
- { name: menu.builder, alias: main }
Render the Menu: In a Twig template:
{{ knp_menu_render('main') }}
Menu Hierarchy: Use nested arrays for submenus:
'items' => [
[
'name' => 'Parent',
'items' => [
['name' => 'Child', 'route' => 'child_route'],
],
],
]
Dynamic Menus:
Inject services (e.g., Security, Router) into the builder:
use Symfony\Component\Security\Core\SecurityContextInterface;
class MainMenu {
private $security;
public function __construct(SecurityContextInterface $security) {
$this->security = $security;
}
public function getMenu() {
if (!$this->security->isGranted('ROLE_ADMIN')) {
return [];
}
// ...
}
}
Route-Based Menus:
Use route keys for URL generation:
'items' => [
['name' => 'Dashboard', 'route' => 'dashboard', 'routeParameters' => ['id' => 1]],
]
Twig Integration:
{{ knp_menu_render('alias') }}{{ knp_menu_render('main', { 'depth': 2, 'currentClass': 'active' }) }}
Event-Driven Extensions:
Listen to menu.build events to modify menus globally:
services.menu.listener:
class: AppBundle\EventListener\MenuListener
tags:
- { name: kernel.event_listener, event: menu.build, method: onBuildMenu }
Namespace Mismatch:
The README references Knp\Bundle\Desarrolla2\MenuBundle, but the correct namespace is Desarrolla2\MenuBundle\Desarrolla2MenuBundle. Double-check in AppKernel.php.
Service Tagging:
Ensure the menu.builder tag uses the correct alias (e.g., alias: main). Misspelled aliases will break rendering.
Route Resolution: If routes fail, verify:
routing.yml/config/routes.yaml.routeParameters are correctly formatted (e.g., ['id' => 1]).Caching: Menus are cached by default. Clear the cache after changes:
php bin/console cache:clear
Deprecated Symfony 2:
This bundle is designed for Symfony 2.x. If using Symfony 4/5/6, expect compatibility issues (e.g., AppKernel, services.yml syntax).
Dump Menu Structure: Add a temporary dump in the builder:
var_dump($this->getMenu()); die();
Check Registered Menus: Run:
php bin/console debug:container | grep menu.builder
Twig Debugging:
Enable Twig debug mode in config/packages/twig.yaml:
twig:
debug: true
strict_variables: true
Custom Menu Items:
Extend the MenuInterface to add metadata (e.g., priority, permissions):
interface MenuInterface {
public function getMenu();
public function getPriority(); // e.g., return 100;
}
Override Twig Rendering: Create a custom Twig extension to modify the default template:
class CustomMenuExtension extends \Twig_Extension {
public function getFunctions() {
return [
new \Twig_SimpleFunction('custom_menu_render', [$this, 'renderMenu']),
];
}
}
Database-Driven Menus:
Fetch menu items from a DB in getMenu() and structure them into the expected array format.
AJAX Menus:
Use the ajax option in menu items to enable dynamic loading:
'items' => [
[
'name' => 'Dynamic Content',
'route' => 'ajax_route',
'ajax' => true,
],
]
(Note: Requires frontend JS to handle the response.)
How can I help you explore Laravel packages today?