Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Menu Bundle Laravel Package

c33s/menu-bundle

Routing-based menu system for Symfony2. MenuBundle builds navigation menus from your routing configuration, helping you keep menu structure in sync with routes and simplify link management across your application.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require c33s/menu-bundle
    

    Add to config/bundles.php:

    return [
        // ...
        C33S\MenuBundle\C33SMenuBundle::class => ['all' => true],
    ];
    
  2. Basic Configuration Create a YAML menu definition in config/menus.yml:

    main:
        items:
            home:
                label: 'Home'
                route: 'homepage'
            about:
                label: 'About'
                route: 'about'
    
  3. First Usage In a Twig template:

    {{ menu('main') }}
    

    Or in a controller:

    return $this->render('template.html.twig', [
        'menu' => $this->get('c33s_menu.menu_builder')->build('main'),
    ]);
    
  4. Key Files to Review

    • config/menus.yml (default config location)
    • src/C33S/MenuBundle/Builder/MenuBuilder.php (core logic)
    • Resources/views/Menu/menu.html.twig (default Twig template)

Implementation Patterns

Common Workflows

  1. Dynamic Menu Building Use the MenuBuilder service to programmatically construct menus:

    $menu = $this->get('c33s_menu.menu_builder')
        ->build('main')
        ->addChild('contact', [
            'label' => 'Contact',
            'route' => 'contact',
        ]);
    
  2. Route-Based Menus Leverage Symfony’s routing system for automatic active state:

    admin:
        items:
            dashboard:
                label: 'Dashboard'
                route: 'admin_dashboard'
                active: 'equals'  # Checks if current route matches
    
  3. Nested Menus Define hierarchical menus in YAML:

    navigation:
        items:
            products:
                label: 'Products'
                route: 'products_index'
                children:
                    electronics:
                        label: 'Electronics'
                        route: 'products_electronics'
    
  4. Twig Integration Use Twig extensions for flexible rendering:

    {% for item in menu('main').children %}
        <li class="{{ item.isActive ? 'active' }}">
            <a href="{{ path(item.route) }}">{{ item.label }}</a>
        </li>
    {% endfor %}
    
  5. Event-Driven Customization Subscribe to c33s_menu.menu_builder.build event to modify menus:

    // In a service
    public function onBuildMenu(MenuEvent $event) {
        $menu = $event->getMenu();
        $menu->addChild('custom_item', ['label' => 'Dynamic Item']);
    }
    
  6. Cache Optimization Enable caching in config.yml:

    c33s_menu:
        cache: true
        cache_lifetime: 3600
    

Integration Tips

  1. Symfony Flex Compatibility If using Symfony Flex, place menu configs in config/packages/c33s_menu.yaml:

    c33s_menu:
        menus:
            main:
                items:
                    home: { label: 'Home', route: 'home' }
    
  2. Dependency Injection Inject MenuBuilder directly into services:

    public function __construct(MenuBuilder $menuBuilder) {
        $this->menuBuilder = $menuBuilder;
    }
    
  3. Active State Logic Customize active state checks via active option:

    items:
        blog:
            label: 'Blog'
            route: 'blog_index'
            active: 'contains'  # Checks if current route contains 'blog'
    
  4. Translation Support Use Twig’s trans filter for labels:

    items:
        home:
            label: 'menu.home'  # Translatable key
            route: 'home'
    
    {{ item.label|trans }}
    
  5. Security Integration Combine with Symfony’s security component:

    items:
        admin:
            label: 'Admin'
            route: 'admin'
            access_control: 'ROLE_ADMIN'
    

Gotchas and Tips

Common Pitfalls

  1. Route Name Mismatches

    • Issue: Menu items fail to link if route names are incorrect.
    • Fix: Verify route names with php bin/console debug:router.
    • Tip: Use path() in Twig to auto-generate URLs:
      <a href="{{ path(item.route) }}">{{ item.label }}</a>
      
  2. Caching Headaches

    • Issue: Menus not updating after changes to menus.yml.
    • Fix: Clear cache:
      php bin/console cache:clear
      
    • Tip: Disable caching in dev:
      c33s_menu:
          cache: '%kernel.debug%'
      
  3. Active State Logic Errors

    • Issue: active option not working as expected.
    • Fix: Default options are:
      • equals: Exact route match.
      • contains: Route contains the item’s route.
      • regex: Custom regex match.
    • Tip: Debug with:
      {{ dump(item.isActive) }}
      
  4. YAML Parsing Quirks

    • Issue: Complex nested menus break.
    • Fix: Ensure proper indentation (2 spaces per level).
    • Tip: Use an online YAML validator for complex configs.
  5. Event Subscriber Conflicts

    • Issue: Multiple subscribers modifying the same menu.
    • Fix: Use priority in subscriber tags:
      tags:
          - { name: kernel.event_listener, event: c33s_menu.menu_builder.build, method: onBuildMenu, priority: 100 }
      

Debugging Tips

  1. Dump Menu Structure

    {{ dump(menu('main')) }}
    

    Or in PHP:

    var_dump($menu->toArray());
    
  2. Check Event Dispatch Enable debug mode to see fired events:

    php bin/console debug:event-dispatcher
    
  3. Override Default Twig Template Copy vendor/c33s/menu-bundle/Resources/views/Menu/menu.html.twig to templates/Menu/menu.html.twig for customization.

Extension Points

  1. Custom Menu Builders Extend MenuBuilder to add logic:

    class CustomMenuBuilder extends MenuBuilder {
        public function build($name) {
            $menu = parent::build($name);
            // Add custom logic
            return $menu;
        }
    }
    

    Register as a service:

    services:
        c33s_menu.menu_builder.custom:
            class: App\Menu\CustomMenuBuilder
            tags: ['c33s_menu.menu_builder']
    
  2. Dynamic Menu Items Use MenuItem class to create items programmatically:

    $item = new MenuItem('dynamic_item', [
        'label' => 'Dynamic Item',
        'route' => 'dynamic_route',
    ]);
    $menu->addChild($item);
    
  3. Custom Active State Providers Implement C33S\MenuBundle\Provider\ActiveStateProviderInterface for custom logic:

    class CustomActiveStateProvider implements ActiveStateProviderInterface {
        public function isActive(MenuItem $item, Request $request) {
            // Custom logic
            return $request->get('_route') === 'custom_route';
        }
    }
    

    Register in config:

    c33s_menu:
        active_state_provider: 'app.custom_active_state_provider'
    
  4. Menu Item Classes Extend MenuItem for custom properties:

    class ExtendedMenuItem extends MenuItem {
        protected $extraData;
    
        public function setExtraData($data) {
            $this->extraData = $data;
        }
    }
    

    Use in YAML:

    items:
        custom:
            class: App\Menu\ExtendedMenuItem
            extra_data: { key: 'value' }
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
croct/coding-standard
croct/plug-php
nqxcode/phpmorphy
boundwize/pyrameter
testo/facade
headercat/phpstan-extension-ide-helper
yosymfony/parser-utils
innmind/black-box
babenkoivan/elastic-migrations
babenkoivan/elastic-adapter
develia/commons
dmstr/symfony-system-resources-bundle
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
renatomarinho/laravel-page-speed
develia/geo-bundle
austinheap/laravel-database-encryption
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle