camurphy/bootstrap-menu-bundle
Installation
composer require camurphy/bootstrap-menu-bundle
Ensure Camurphy\BootstrapMenuBundle\BootstrapMenuBundle is enabled in config/bundles.php.
Configure Menus
Define menus in config/packages/bootstrap_menu.yaml:
bootstrap_menu:
menus:
main:
items:
home:
label: 'Home'
route: 'homepage'
about:
label: 'About'
route: 'about'
Render in Twig
Use the render_bootstrap_menu function in your template:
{{ render_bootstrap_menu('main', {
'navbar_class': 'navbar-expand-lg navbar-dark bg-dark',
'container_class': 'container-fluid'
}) }}
Create a responsive navbar for your Symfony app with dynamic routes. Start with a simple main menu, then expand with dropdowns, icons, or active state logic.
Basic Structure Define menus hierarchically in YAML:
menus:
admin:
items:
dashboard:
label: 'Dashboard'
route: 'admin_dashboard'
users:
label: 'Users'
route: 'admin_users'
children:
- { label: 'List', route: 'admin_users_list' }
- { label: 'Create', route: 'admin_users_create' }
Dynamic Items Use Twig logic to conditionally render items:
items:
profile:
label: 'Profile'
route: 'user_profile'
show: "@= user.isAuthenticated()"
Bootstrap Versioning Specify version globally or per menu:
bootstrap_menu:
version: 4 # Overrides default (5)
menus:
legacy:
version: 4 # Per-menu override
Twig Extensions Access menu items directly in templates:
{% for item in bootstrap_menu('main').items %}
{{ item.label }}
{% endfor %}
Active State Logic
Use active or active_when keys:
items:
posts:
label: 'Posts'
route: 'posts_index'
active: true # Always active
# OR
active_when: "@= request.get('_route') == 'posts_show'"
Icons & Attributes Add Bootstrap icons or custom attributes:
items:
notifications:
label: 'Notifications'
route: 'notifications'
icon: 'bell'
attributes:
class: 'nav-link'
data-toggle: 'tooltip'
title: 'New messages'
Dropdowns Define nested menus for dropdowns:
items:
products:
label: 'Products'
route: 'products_index'
dropdown: true
children:
- { label: 'All', route: 'products_index' }
- { label: 'Featured', route: 'products_featured' }
Authentication-Aware Menus Combine with Symfony’s security component:
items:
login:
label: 'Login'
route: 'app_login'
show: "@= not user.isAuthenticated()"
logout:
label: 'Logout'
route: 'app_logout'
show: "@= user.isAuthenticated()"
Caching Issues
php bin/console cache:clear
config/packages/bootstrap_menu.yaml for development:
bootstrap_menu:
cache: false
Route Resolution
route_exists in Twig:
{% if route_exists('nonexistent_route') %}
{{ render_bootstrap_menu('main') }}
{% endif %}
Bootstrap Version Mismatches
Twig Syntax in YAML
@= for comparisons (e.g., @= user.isAuthenticated()), not ==. Avoid complex logic in YAML; offload to Twig when possible.Dropdown Styling
dropdown_active_style and dropdown_item_active_style default to false. Enable if you want active dropdown items styled:
bootstrap_menu:
dropdown_active_style: true
Dump Menu Data
Use Twig’s dump to inspect menu structure:
{{ dump(bootstrap_menu('main')) }}
Check for Typos
items: must be at the same level as menus:).Custom Renderers Override the Twig renderer by extending the bundle’s service:
# config/services.yaml
Camurphy\BootstrapMenuBundle\Twig\BootstrapMenuExtension:
arguments:
$renderer: '@custom.bootstrap_menu.renderer'
Add Menu Providers Dynamically inject menu items via services:
// src/Service/MenuProvider.php
class MenuProvider implements MenuProviderInterface {
public function getMenuItems(): array {
return ['dynamic_item' => ['label' => 'Dynamic', 'route' => 'dynamic']];
}
}
Register in services.yaml:
services:
App\Service\MenuProvider:
tags: [bootstrap_menu.provider]
Override Twig Functions
Extend the BootstrapMenuExtension to add custom functions (e.g., render_menu_as_list).
Lazy-Load Menus
For large menus, use cache: true and clear selectively:
php bin/console cache:pool:clear bootstrap_menu.cache_pool
Avoid Over-Fetching
Only define items you need. Use show conditions to hide unused items.
Responsive Behavior
Ensure navbar_class includes responsive classes (e.g., navbar-expand-lg). The bundle doesn’t auto-add these.
Active State Conflicts
If using both active and active_when, active_when takes precedence.
Icon Integration Requires Bootstrap Icons or another icon library. Add to your base template:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.0/font/bootstrap-icons.css">
How can I help you explore Laravel packages today?