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

Vedi Menu Bundle Laravel Package

blackator/vedi-menu-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require blackator/vedi-menu-bundle
    

    Ensure BlackatorVediMenuBundle is enabled in config/bundles.php (Symfony Flex handles this automatically).

  2. First Use Case: Basic YAML Menu

    • Create a YAML file at config/menu/main_menu.yaml:
      items:
        - label: 'Home'
          route: 'home'
        - label: 'About'
          route: 'about'
      
    • Inject 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 in Twig:
      {{ render_menu(menu) }}
      
  3. 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.


Implementation Patterns

Core Workflow

  1. 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'
    
  2. 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]);
    }
    
  3. Twig Integration

    • Use render_menu() for full rendering.
    • Access raw menu data with menu.items or iterate manually:
      <ul>
        {% for item in menu.items %}
          <li><a href="{{ path(item.route) }}">{{ item.label }}</a></li>
        {% endfor %}
      </ul>
      
  4. 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();
        }
    }
    

Best Practices

  • Organization: Group menu files by context (e.g., config/menu/admin/, config/menu/public/).
  • Caching: Leverage Symfony’s cache system for YAML menus by implementing CacheInterface in your loader.
  • Reusability: Create base menu configurations and override them for specific contexts (e.g., main_menu.yaml + main_menu_admin.yaml).

Gotchas and Tips

Pitfalls

  1. Loader Initialization

    • Issue: Forgetting to pass the full path to YAML files (e.g., using relative paths).
    • Fix: Always use $this->getParameter('kernel.project_dir') for absolute paths.
      new YamlMenuLoader($this->getParameter('kernel.project_dir').'/config/menu/main_menu.yaml')
      
  2. Twig Template Overrides

    • Issue: Overriding the template path incorrectly (e.g., templates/vedimenu/default.html.twig instead of templates/bundles/vedimenu/default.html.twig).
    • Fix: Use the exact bundle path: @VediMenu/default.html.twig or copy to templates/bundles/vedimenu/.
  3. Route Resolution

    • Issue: Routes not found in Twig (path(item.route) fails).
    • Fix: Ensure routes are properly defined in config/routes.yaml and the bundle is loaded before the router.
  4. Nested Menus

    • Issue: Children items not rendering in the default template.
    • Fix: Customize the Twig template to handle nested structures:
      {% 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 %}
      

Debugging Tips

  • Dump Menu Data: Use var_dump($menu->getItems()) to inspect loaded data.
  • Loader Errors: Check for InvalidArgumentException if YAML is malformed (e.g., missing items key).
  • Caching Issues: Clear cache (php bin/console cache:clear) if menus don’t update after changes.

Extension Points

  1. Custom Loaders Extend AbstractMenuLoader to support:

    • Database queries.
    • API responses.
    • Environment-specific configurations.
  2. 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 }
    
  3. 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']),
            ];
        }
    }
    
  4. Configuration Override bundle parameters in config/packages/vedi_menu.yaml (if supported):

    blackator_vedi_menu:
        default_template: 'custom/path.html.twig'
    
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.
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui