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

Darvin Menu Bundle Laravel Package

darvinstudio/darvin-menu-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install the Bundle Add the package via Composer:

    composer require darvinstudio/darvin-menu-bundle
    

    Enable the bundle in config/bundles.php:

    return [
        // ...
        DarvinStudio\MenuBundle\DarvinMenuBundle::class => ['all' => true],
    ];
    
  2. Configure a Menu Define a menu in config/packages/darvin_menu.yaml:

    darvin_menu:
        menus:
            header: ~  # Minimal config; items are defined via annotations or YAML later
    
  3. First Render Use the ESI controller to render the menu in Twig:

    {{ render_esi(controller('darvin_menu.controller.menu', {
        'buildOptions': {'menu': 'header', 'depth': 2},
        'renderOptions': {'template': 'menu/header.html.twig'}
    })) }}
    
    • Ensure menu/header.html.twig exists in your templates directory.
    • The depth parameter limits nesting (e.g., 2 shows top-level + one sub-level).
  4. Define Menu Items Use annotations (e.g., @MenuItem) on controllers/actions or configure via YAML in config/packages/darvin_menu.yaml:

    darvin_menu:
        menus:
            header:
                items:
                    - route: 'homepage'
                      label: 'Home'
                    - route: 'about'
                      label: 'About'
                      children:
                          - route: 'team'
                            label: 'Team'
    

Implementation Patterns

Common Workflows

  1. Dynamic Menu Building

    • Route-Based Menus: Leverage Symfony routes for dynamic links:
      darvin_menu:
          menus:
              admin:
                  items:
                      - route: 'admin_dashboard'
                        label: 'Dashboard'
                        acl: 'ROLE_ADMIN'
      
    • Controller Annotations: Tag actions with @MenuItem for automatic inclusion:
      use DarvinStudio\MenuBundle\Annotation\MenuItem;
      
      class AdminController {
          /**
           * @MenuItem(menu="admin", label="Users", route="admin_users")
           */
          public function usersAction() { ... }
      }
      
  2. Conditional Rendering

    • Use acl or condition in YAML to show/hide items:
      items:
          - route: 'user_profile'
            label: 'Profile'
            condition: 'app.user.is_authenticated'
      
    • Pass runtime conditions via buildOptions:
      {{ render_esi(controller('darvin_menu.controller.menu', {
          'buildOptions': {
              'menu': 'header',
              'context': {'show_promo': true}
          }
      })) }}
      
  3. Template Customization

    • Override the default template (menu/default.html.twig) by specifying a custom path in renderOptions:
      {{ render_esi(controller('darvin_menu.controller.menu', {
          'renderOptions': {'template': 'AppBundle:menu/custom.html.twig'}
      })) }}
      
    - Extend the base template to add classes or modifiers:
      ```twig
      {% extends 'menu/default.html.twig' %}
      {% block menu_item_class %}
          {{ parent() }} active
      {% endblock %}
    
  4. Menu Switcher

    • Enable the menu switcher (documented in menu_switcher.md) to let users toggle menus dynamically:
      {{ render_esi(controller('darvin_menu.controller.menu_switcher', {
          'menu': 'header',
          'activeMenu': 'footer'
      })) }}
      
  5. Caching

    • Enable caching for menus to improve performance:
      darvin_menu:
          menus:
              header:
                  cache: true
                  cache_lifetime: 3600  # 1 hour
      

Gotchas and Tips

Pitfalls

  1. ESI Controller Dependency

    • The bundle relies on Symfony’s ESI controller. Ensure:
      • The framework.esic option is enabled in config/packages/framework.yaml:
        framework:
            esic: true
        
      • Your web server (e.g., Nginx/Apache) supports ESI headers.
  2. Annotation Processing

    • Annotations (e.g., @MenuItem) require the doctrine/annotations bundle. Add it if missing:
      composer require doctrine/annotations
      
    • Clear the cache after adding annotations:
      php bin/console cache:clear
      
  3. Depth Limitation

    • The depth parameter in buildOptions is inclusive. A value of 1 shows only top-level items, while 2 includes one level of children. Misconfiguration may lead to missing or excessive nesting.
  4. Route Resolution

    • Menu items with route keys must resolve to valid Symfony routes. Use absolute routes (e.g., _route: 'app_home') or ensure the route is loaded before rendering.
  5. Template Inheritance

    • Overriding templates requires careful handling of blocks like menu_item_class or menu_item_attributes. Always extend the parent template to avoid breaking functionality.

Debugging

  1. Check Menu Dump Use the debug command to inspect menu structure:

    php bin/console darvin:menu:dump
    
    • Outputs the raw menu data to var/log/darvin_menu_dump.log.
  2. Log Build Errors Enable debug mode in config/packages/dev/darvin_menu.yaml:

    darvin_menu:
        debug: true
    
    • Logs menu-building errors to var/log/dev.log.
  3. ESI Issues

    • If ESI rendering fails, verify:
      • The controller path is correct (darvin_menu.controller.menu).
      • The template path is accessible (e.g., menu/header.html.twig exists).
      • The web server is configured to handle ESI (e.g., Nginx fastcgi_hide_esi or Apache mod_esi).

Tips

  1. Reuse Menus Define menus once in YAML and reuse them across templates:

    {# Footer menu #}
    {{ render_esi(controller('darvin_menu.controller.menu', {
        'buildOptions': {'menu': 'footer', 'depth': 1}
    })) }}
    
  2. Localization Use Twig’s trans filter for labels:

    darvin_menu:
        menus:
            header:
                items:
                    - route: 'homepage'
                      label: 'menu.home'  # Translatable key
    
    {{ render_esi(controller('darvin_menu.controller.menu', {
        'renderOptions': {'translation_domain': 'messages'}
    })) }}
    
  3. Dynamic Items Add items programmatically via events:

    use DarvinStudio\MenuBundle\Event\MenuBuildEvent;
    
    public function onMenuBuild(MenuBuildEvent $event) {
        $menu = $event->getMenu();
        $menu->addChild('dynamic_item', [
            'route' => 'dynamic_route',
            'label' => 'Dynamic Label'
        ]);
    }
    

    Register the subscriber in services.yaml:

    services:
        App\EventSubscriber\MenuSubscriber:
            tags:
                - { name: kernel.event_subscriber }
    
  4. Performance

    • Cache menus aggressively for static sites.
    • Use cache_lifetime: 0 to disable caching for dynamic menus.
  5. Testing Mock the ESI controller in PHPUnit:

    $this->container->get('twig')->addFunction(
        new \Twig_SimpleFunction('render_esi', function ($args) {
            return $this->renderView('menu/header.html.twig', $args);
        })
    );
    
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.
nasirkhan/laravel-sharekit
directorytree/privacy-filter-classifier
directorytree/privacy-filter
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity
testo/bridge-symfony