Weave 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

aropixel/menu-bundle

A Symfony bundle that extends Aropixel Admin Bundle to manage your website's menus (main menu, footer, and more), with routes, migrations, and support for six languages. Requires Symfony 4 and the admin bundle.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Requirements (v3.0):

    • aropixel/admin-bundle ^3.0 (mandatory — 3.0 is a rewrite on top of it)
    • Symfony 6.4, 7.x, or 8.x
    • Doctrine ORM 2 or 3
  2. Installation:

    composer require aropixel/menu-bundle:^3.0
    

    Follow doc/installation.md in the v3.0.0 tag — the 2.x install steps (separate yaml, route include, manual migration order) no longer match the rewritten setup.

  3. Upgrading from 2.x — read this first: There is no in-place upgrade path. Do not run composer update aropixel/menu-bundle on an existing 2.x install expecting it to work. Read UPGRADE-3.0.md and the installation guide before touching production. Treat 3.0 as a fresh integration.

  4. Configuration: Menus are still defined in config with per-menu depth, but the editor is now embedded in the AdminBundle 3.0 UI. Register menus there rather than in the old standalone admin route:

    aropixel_menu:
        menus:
            main:
                name: "Main Menu"
                depth: 3
    
  5. First use case: Open the menu editor from within the AdminBundle 3.0 admin (no separate /admin/menu route as in 2.x). Build the main menu via the configurable, drag-and-drop editor, then render it on the front end with the helpers in doc/front-end.md.


Implementation Patterns

Core Workflow

  1. Admin management:

    • Manage menus through the AdminBundle 3.0 UI.
    • Configure menus and depth per menu in yaml; the editor respects those settings.
    • Use built-in sources, or the new pluggable item sources (see doc/sources.md) for custom content.
  2. Front-end rendering: The v3 rendering helpers live in doc/front-end.md — use those rather than the 2.x Twig idioms, which changed with the rewrite. Typical pattern:

    <nav>
        {% for item in get_menu('main') %}
            <a href="{{ item|get_link }}">{{ item.title }}</a>
        {% endfor %}
    </nav>
    

    Verify exact function/filter names against doc/front-end.md for 3.0.0 before porting 2.x templates.

  3. Custom item sources (v3 pluggable sources): Custom sources are a first-class concept in 3.0 — register them per doc/sources.md.

    class ProductMenuSource implements MenuSourceInterface {
        public function getAvailableItems(array $menuItems): array {
            return $this->productRepository->findAll()->map(fn($p) => [
                'value' => $p->getId(),
                'label' => $p->getName(),
                'type'  => 'product',
            ]);
        }
        // ... remaining required methods per 3.0 interface
    }
    

    Re-verify the interface signature for 3.0 — it is part of the rewrite and should not be assumed identical to 2.x.

  4. Custom entity integration: Extend the base Menu entity to add fields, then point config at it:

    #[ORM\Entity]
    class Menu extends BaseMenu {
        #[ORM\Column(type: 'boolean')]
        private bool $newTab = false;
    }
    
    aropixel_menu:
        entity: App\Entity\Menu
    

    Confirm the config key still exists in 3.0 before relying on it (see doc/installation.md).

  5. Nested menus: Set depth per menu; iterate children recursively in Twig.

    {% for item in get_menu('main') %}
        <li>
            <a href="{{ item|get_link }}">{{ item.title }}</a>
            {% if item.children|length > 0 %}
                <ul>{% include 'menu/_nested.html.twig' with {'items': item.children} %}</ul>
            {% endif %}
        </li>
    {% endfor %}
    

Gotchas and Tips

Pitfalls

  1. No in-place upgrade: The single biggest 3.0 trap. composer update on a 2.x project will break things. Follow UPGRADE-3.0.md and plan a migration, not an upgrade.

  2. AdminBundle 3.0 is a hard requirement: 3.0 is built on AdminBundle ^3.0. If your app is pinned to AdminBundle 2.x, you cannot install MenuBundle 3.0. Upgrade AdminBundle first.

  3. Symfony / Doctrine version gates: Symfony 6.4+, 7.x or 8.x, Doctrine ORM 2 or 3. Older Symfony or ORM 1.x projects must upgrade before adopting 3.0.

  4. Editor location changed: The menu editor is now inside the AdminBundle UI, not a standalone /admin/menu route. If a 2.x link, bookmark or test hits the old route, update it.

  5. Route / config includes from 2.x: config/routes.yaml includes and the aropixel_menu.yaml structure should be re-checked against doc/installation.md — the rewrite may change which files are loaded.

  6. Source interface changes: Custom sources written for 2.x may not compile against 3.0. Re-implement against the 3.0 interface documented in doc/sources.md.

  7. Front-end helpers changed: Twig function/filter names and signatures for rendering may differ. Port templates against doc/front-end.md and test each one.

  8. Caching: Menus may appear stale after edits; clear the cache:

    php bin/console cache:clear
    

Debugging Tips

  1. Locate registered sources: Inspect the source chain service from a dev console or a debug template after confirming the 3.0 service ID.

    {{ dump(app.container.get('aropixel_menu.source_chain').getSources()) }}
    
  2. Log resolved menu items: Decorate / extend the menu handler and log output:

    class CustomMenuHandler extends MenuHandler {
        public function getMenuItems(string $menuCode): array {
            $items = parent::getMenuItems($menuCode);
            \Log::info('Menu items for '.$menuCode, ['items' => $items]);
            return $items;
        }
    }
    
  3. Verify link resolution:

    {{ item|get_link|dump }}
    
  4. Schema check: If the new migrations fail, inspect the menu table — the nested-set columns (lft, rgt, parent_id) and types should match what the 3.0 migrations expect.

Extension Points

  1. Custom menu handlers: Extend MenuHandler to filter or transform items, and register as a service (tag name may differ in 3.0 — verify).

    class CustomMenuHandler extends MenuHandler {
        public function getMenuItems(string $menuCode): array {
            return array_filter(
                parent::getMenuItems($menuCode),
                fn($item) => $item->isActive()
            );
        }
    }
    
  2. Override templates: Customize the editor/admin look by overriding AdminBundle 3.0 templates (path may have changed from templates/AropixelMenuBundle/).

  3. Dynamic menu codes: Drive menu definitions from services/parameters:

    aropixel_menu:
        menus: '%menu_codes%'
    
  4. Validation on items: Add constraints on your extended Menu entity:

    #[Assert\Callback]
    public function validate(ExecutionContextInterface $context): void {
        if ($this->type === 'page' && empty($this->link)) {
            $context->buildViolation('Page link is required')->addViolation();
        }
    }
    
  5. Performance:

    • Index parent_id and type.
    • Filter to published/active items in DQL rather than post-filtering.
    • Fetch with the nested-set strategy the bundle uses rather than per-node queries.

Pro Tips

  1. Do a dry-run on a throwaway branch: Because there's no in-place upgrade, stand up a fresh 3.0 install on a branch, wire the config and sources, confirm the front end matches, then migrate.

  2. Multi-language menus: Add translated title fields on your extended entity and filter per locale in getAvailableItems().

  3. Preview images: Add a previewUrl field to the Menu entity and render it in the editor template.

  4. API exposure:

    #[Route('/api/menus/{code}', name: 'api_menu_get', methods: ['GET'])]
    public function getMenu(string $code, MenuHandler $handler): JsonResponse {
        return new JsonResponse($handler->getMenuItems($code));
    }
    
  5. Testing: Assert structure via the handler in PHPUnit:

    public function testMainMenuStructure(): void {
        $handler = $this->container->get(MenuHandler::class);
        $menu = $handler->getMenuItems('main');
        $this->assertCount(3, $menu);
    }
    
  6. Keep the doc links handy: doc/installation.md, doc/sources.md, doc/front-end.md, and UPGRADE-3.0.md in the v3.0.0 tag are the authoritative source for 3.0 — the 2.x docs online may be stale.

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.
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels