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

Nadia Menu Bundle Laravel Package

nadialabs/nadia-menu-bundle

Nadia Menu Bundle is a PHP package for defining, rendering, and managing menus in your application. Build nested navigation trees, control access and active states, and output flexible menu structures with minimal configuration.

View on GitHub
Deep Wiki
Context7

Getting Started

First, calibrate expectations: this is a Symfony bundle, not a Laravel package. It extends knplabs/knp-menu-bundle with security-aware checks (role/expression gating on menu items). With 0 stars, 0 dependents, and no ecosystem signal, treat it as read-before-you-run code, not a drop-in dependency. Read src/ and the bundle's DependencyInjection/ extension first — that is the actual documentation.

Minimal path:

  1. Require it alongside its assumed peers:
    composer require nadialabs/nadia-menu-bundle knplabs/knp-menu-bundle symfony/security-bundle
    
  2. Register the bundle in config/bundles.php (Symfony Flex may not auto-register it):
    NadiaLabs\NadiaMenuBundle\NadiaMenuBundle::class => ['all' => true],
    
    Confirm the real namespace from composer.json's autoload.psr-4 — do not assume it matches the vendor string.
  3. Inspect the DI extension for the config tree (Configuration.php) and any service IDs it defines. That tells you what is configurable (security_check, voter service, expression language) versus hardcoded.
  4. First use case: gate a menu item on a role so unprivileged users don't see the link.
$menu->addChild('Admin', ['route' => 'admin_dashboard'])
     ->setAttribute('security', ['role' => 'ROLE_ADMIN']);

The exact attribute/config key must be verified against the source — the bundle's whole point is translating a per-item security declaration into a KnpMenu voter decision.

If you are on Laravel, stop here. There is no Laravel adapter, no service provider, no facade — you would be porting the security-check logic into your own menu builder. That is usually ~40 lines of code and better done yourself than by pulling in a zero-signal Symfony bundle.

Implementation Patterns

Security-as-a-voter. The intended integration is a KnpMenu VoterInterface implementation that inspects item attributes and returns VoterInterface::ITEM_... decisions. Your controllers/builders stay ignorant of AuthorizationChecker; the menu system filters automatically at render time. Lean on this — do not sprinkle isGranted() calls inside MenuBuilder methods, or you lose the ability to reuse the same tree definition across contexts (e.g. CLI renderers where no token exists).

Declarative item attributes. Standard pattern:

  • Role checks: ['security' => 'ROLE_X']
  • Expression checks: ['security' => "is_granted('EDIT', subject)"]` — requires the ExpressionLanguage service wired through the bundle config.
  • Nested inheritance: whether a parent's check cascades to children is the single most important thing to verify in the source. Most implementations do not cascade; a hidden parent with visible children produces orphaned links.

Integration with the renderer. KnpMenu renders the tree it is given. Whether this bundle filters at build time or at render time matters:

  • Build-time filtering: cheap, but caches badly if you memoize the menu.
  • Render-time filtering: correct per-request, but the voter runs on every node.

Check which one it does before you cache a MenuFactory result in a shared service.

Testing. Build the menu in a kernel test with a mocked/stubbed TokenStorage, assert which children survive. Write a table test: [role, expected visible items]. This is the only reliable way to pin behavior given thin docs — and it protects you if you later fork the bundle.

Extension point to prefer. If the built-in check is too coarse, register your own KnpMenu voter with a higher priority rather than editing vendor code. Custom voters compose; forks rot.

Gotchas and Tips

  • Framework mismatch is the first gotcha. Symfony bundle, not Laravel. composer require in a Laravel app will pull the bundle but nothing wires it up. Check composer.json's type (symfony-bundle) and require constraints before anything else.
  • Maintenance risk is real. 0 stars / 0 dependents means no one is filing bugs, so latent incompatibilities with current KnpMenu or Symfony Security versions are unpatched. Pin the version exactly and add a composer.lock note; budget a fork.
  • Version skew with KnpMenu. VoterInterface::vote() signatures and the ItemInterface API have churned across KnpMenu majors. Confirm the bundle's require constraint against what you have installed; a silent API mismatch surfaces as an item that is always hidden or always shown.
  • "Always visible" is the classic failure mode. When a voter returns ITEM_ABSTAIN and no other voter decides, KnpMenu defaults to show. If a security check throws (missing expression variable, null token in a CLI/queue context), you may get an unguarded menu rather than a closed one. Decide explicitly whether your policy is allow-list or deny-list, and test the anonymous/no-token case.
  • Expression variables need context. Expression-based checks referencing route params, request attributes, or domain objects require those to be passed into the voter's context. Undefined variables throw at render time — a runtime 500 on the layout, not a graceful menu omission. Wrap the render path in a smoke test that hits every menu.
  • Caching caveat. If you cache the rendered menu (HTTP cache, fragment cache, Twig cache with a shared key), you will leak one user's visibility to another. Either disable cache for the menu fragment or vary the key by roles/token.
  • Debugging technique. Dump the resolved tree rather than guessing: iterate $menu->getChildren() and print name + getExtra()/attributes after the voter has run. If the bundle exposes a MenuManipulator, run it twice and diff — double-filtering is a common symptom of registering the voter in both bundle config and services.yaml.
  • Config quirks to audit. Look for whether the bundle hardcodes the role prefix (ROLE_), whether it requires the security.authorization_checker alias explicitly, and whether it registers its voter with a priority. The priority determines whether your own voters get a say before it abstains.
  • Escape hatch. If the source is small (likely, for a bundle of this scope), vendor it into src/ under your own namespace, add the tests you need, and drop the composer dependency. For a zero-signal package, owning the 200 lines is lower risk than owning the supply chain.
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.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core