Installation
composer require blackator/vedi-menu-bundle
Ensure BlackatorVediMenuBundle is enabled in config/bundles.php (Symfony Flex handles this automatically).
First Use Case: Basic YAML Menu
config/menu/main_menu.yaml:
items:
- label: 'Home'
route: 'home'
- label: 'About'
route: 'about'
VediMenu in a controller and load the menu:
use Blackator\Bundle\VediMenuBundle\Loaders\YamlMenuLoader;
use Blackator\Bundle\VediMenuBundle\Service\VediMenu;
public function index(VediMenu $vediMenu): Response {
$menu = $vediMenu->create(new YamlMenuLoader($this->getParameter('kernel.project_dir').'/config/menu/main_menu.yaml'), 'main');
return $this->render('home/index.html.twig', ['menu' => $menu]);
}
{{ render_menu(menu) }}
Default Template
The bundle provides a default Twig template at @VediMenu/default.html.twig. Override it by copying it to templates/bundles/vedimenu/default.html.twig.
Menu Definition
Define menus in YAML (or extend AbstractMenuLoader for custom formats like JSON/XML). Example:
# config/menu/admin_menu.yaml
items:
- label: 'Dashboard'
route: 'admin_dashboard'
children:
- label: 'Users'
route: 'admin_users'
Dynamic Menu Loading Load menus dynamically based on user roles or other logic:
public function index(VediMenu $vediMenu, Security $security): Response {
$role = $security->getUser()->getRoles()[0] ?? 'guest';
$menu = $vediMenu->create(new YamlMenuLoader(...), "menu_{$role}");
return $this->render('...', ['menu' => $menu]);
}
Twig Integration
render_menu() for full rendering.menu.items or iterate manually:
<ul>
{% for item in menu.items %}
<li><a href="{{ path(item.route) }}">{{ item.label }}</a></li>
{% endfor %}
</ul>
Menu Extensions
Extend AbstractMenuLoader to support custom data sources (e.g., database):
class DatabaseMenuLoader extends AbstractMenuLoader {
public function load(): array {
return $this->entityManager->getRepository(MenuItem::class)->findAll();
}
}
config/menu/admin/, config/menu/public/).CacheInterface in your loader.main_menu.yaml + main_menu_admin.yaml).Loader Initialization
$this->getParameter('kernel.project_dir') for absolute paths.
new YamlMenuLoader($this->getParameter('kernel.project_dir').'/config/menu/main_menu.yaml')
Twig Template Overrides
templates/vedimenu/default.html.twig instead of templates/bundles/vedimenu/default.html.twig).@VediMenu/default.html.twig or copy to templates/bundles/vedimenu/.Route Resolution
path(item.route) fails).config/routes.yaml and the bundle is loaded before the router.Nested Menus
{% for item in menu.items %}
<li>
<a href="{{ path(item.route) }}">{{ item.label }}</a>
{% if item.children|length > 0 %}
<ul>
{% for child in item.children %}
<li><a href="{{ path(child.route) }}">{{ child.label }}</a></li>
{% endfor %}
</ul>
{% endif %}
</li>
{% endfor %}
var_dump($menu->getItems()) to inspect loaded data.InvalidArgumentException if YAML is malformed (e.g., missing items key).php bin/console cache:clear) if menus don’t update after changes.Custom Loaders
Extend AbstractMenuLoader to support:
Menu Events Listen for menu creation events (if the bundle supports them) to modify menus dynamically:
// config/services.yaml
services:
App\EventListener\MenuSubscriber:
tags:
- { name: kernel.event_subscriber }
Twig Functions
Override or extend Twig functions (e.g., render_menu) by creating a custom Twig extension:
class CustomMenuExtension extends \Twig\Extension\AbstractExtension {
public function getFunctions() {
return [
new \Twig\TwigFunction('custom_render_menu', [$this, 'renderMenu']),
];
}
}
Configuration
Override bundle parameters in config/packages/vedi_menu.yaml (if supported):
blackator_vedi_menu:
default_template: 'custom/path.html.twig'
How can I help you explore Laravel packages today?