Installation:
composer require alpixel/menu-bundle
Register the bundle in config/bundles.php:
return [
// ...
Alpixel\MenuBundle\AlpixelMenuBundle::class => ['all' => true],
];
Database Migration: Run migrations to create the required tables:
php bin/console doctrine:migrations:diff
php bin/console doctrine:migrations:migrate
First Use Case:
Access the admin interface at /admin/menu to create your first menu. Use the built-in CRUD interface to add items, set parent-child relationships, and configure routes/anchors.
/admin/menu – The primary interface for managing menus.Resources/views/AlpixelMenuBundle for default templates.config/packages/alpixel_menu.yaml (if auto-generated).Menu Creation:
app.homepage) or anchors (#contact) to menu items.Dynamic Rendering:
{{ render(knp_menu('main_menu', {'template': 'AlpixelMenuBundle:Menu:main.html.twig'})) }}
templates/AlpixelMenuBundle/Menu/ for custom styling.Sorting and Nesting:
pixassociates/sortable-behavior-bundle.Route-Based Items:
route: 'app.user_profile').routeParameters for dynamic segments (e.g., { id: user.id }).Anchor Links:
# prefixed items (e.g., #services) for page anchors.Symfony Events:
Listen to alpixel_menu.item.pre_save or alpixel_menu.item.post_remove for custom logic:
// src/EventListener/MenuListener.php
public function onMenuItemSave(MenuItemEvent $event) {
$item = $event->getItem();
// Modify $item->setCustomField(...);
}
Register in services.yaml:
services:
App\EventListener\MenuListener:
tags:
- { name: kernel.event_listener, event: alpixel_menu.item.pre_save }
Custom Menu Builders:
Extend Alpixel\MenuBundle\Builder\MenuBuilder to add logic (e.g., hide items based on user roles):
class CustomMenuBuilder extends MenuBuilder {
public function buildMenu() {
$menu = parent::buildMenu();
if (!$this->security->isGranted('ROLE_ADMIN')) {
$menu->removeChild('admin_dashboard');
}
return $menu;
}
}
Configure in config/packages/alpixel_menu.yaml:
alpixel_menu:
builder: App\Builder\CustomMenuBuilder
Translation:
Use trans in menu items (e.g., label: 'app.menu.home'). Ensure translations are loaded in your Twig environment.
Outdated Dependencies:
composer.json or fork the bundle for updates.Missing Migrations:
EntityManager errors.doctrine:migrations:migrate after installation.Caching Issues:
php bin/console cache:clear
Sortable Behavior Quirks:
pixassociates/sortable-behavior-bundle integration can cause JS errors if not configured properly.sortable behavior is enabled in your MenuItem entity.Admin Panel Errors:
var/log/dev.log for Doctrine or Twig exceptions.Menu Not Rendering:
'main_menu' vs. 'mainMenu').{% if menu is not empty %}
{{ knp_menu_render(menu, { 'template': 'AlpixelMenuBundle:Menu:main.html.twig' }) }}
{% endif %}
Route Parameters:
{ id }), ensure the routeParameters are passed correctly:
{{ path('app.user_profile', { id: user.id }) }}
Custom Fields:
Add fields to MenuItem via Doctrine extensions:
// src/Entity/MenuItem.php
/**
* @ORM\Column(type="string", nullable=true)
*/
private $customIcon;
Update the admin form template (Resources/views/AlpixelMenuBundle/MenuItem/_form.html.twig).
Menu Item Types:
Extend the MenuItem entity to support custom types (e.g., "Button," "Divider"):
// src/Entity/MenuItem.php
/**
* @ORM\Column(type="string", enum={"link", "button", "divider"})
*/
private $type = 'link';
Security Trimming:
Use KnpMenu’s SecurityContext to hide items:
$menu->addChild('Admin', ['route' => 'app.admin'])
->setAttribute('security', 'is_granted("ROLE_ADMIN")');
API Access: Expose menu data via API by creating a custom controller:
// src/Controller/ApiMenuController.php
public function getMenu(string $name): JsonResponse {
$menu = $this->menuBuilder->buildMenu($name);
return $this->json($menu->toArray());
}
Default Menu Name:
The admin panel defaults to 'main_menu'. Change it in config/packages/alpixel_menu.yaml:
alpixel_menu:
default_menu: 'primary_navigation'
Template Overrides:
Copy Resources/views/AlpixelMenuBundle/Menu/ to templates/AlpixelMenuBundle/Menu/ to override defaults without modifying the bundle.
Anchor Links:
Ensure anchors are prefixed with # (e.g., #contact). The bundle strips this prefix internally but re-adds it during rendering.
Localization:
Menu items support translation keys (e.g., label: 'app.menu.home'). Ensure your translation files (e.g., translations/messages.en.yaml) include:
app:
menu:
home: Homepage
How can I help you explore Laravel packages today?