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 Module Laravel Package

idavoll/menu-module

A Laravel menu module for defining, organizing, and rendering application navigation. It helps PHP/Laravel projects manage menu structures and keep navigation configuration maintainable.

View on GitHub
Deep Wiki
Context7

Getting Started

Treat this as an AsgardCMS module, not a standalone Composer library. It will not boot without AsgardCMS's module loader, its Menu entity migrations, and the admin theme in place.

  1. Confirm the container. You almost certainly have an existing AsgardCMS install (Laravel 5.x era). Check composer.json for asgardcms/* packages and confirm which Laravel version is pinned — this module predates Laravel 6/7 conventions and will not drop into a modern app.
  2. Install into the CMS, not into a bare Laravel project.
    composer require idavoll/menu-module
    php artisan module:list        # confirm "Menu" is registered
    php artisan module:migrate Menu
    
    The module lives in Modules/Menu/. That directory is your primary reference.
  3. Look here first, in this order:
    • Modules/Menu/Entities/Menu.php and MenuItem.php — the actual schema contract (fields like name, title, position, link_type, page_id, uri, target, class).
    • Modules/Menu/Repositories/* — how menus are queried and what eager-loads exist (watch for N+1 on nested items).
    • Modules/Menu/Http/Controllers/ and Routes/ — the admin surface and backend route names.
    • Modules/Menu/Resources/views/ — the Blade partial(s) you will end up overriding for theming.
  4. First use case — get one menu rendering end to end:
    • Log in to the backend, go to Menus (/backend/menu/menus or the route from Routes/), create a menu with machine name main.
    • Add two items — one Page link and one URL link — and one child item to verify nesting.
    • Render it in a Blade view using the module's facade/helper (verify the exact call in the module's service provider — typically something like {!! Menu::render('main') !!} or a @menu('main') directive).
    • If it renders empty, you've hit the most common first-run issue: the menu must be marked enabled/active and items must have a non-null position.

Implementation Patterns

Admin-managed menus + theme render. The intended workflow is non-developers manage menus in /backend, and your Blade layout renders them by machine name. Keep your theme templates calling a single helper so you can swap the renderer later.

Two link strategies. Menu items generally support a polymorphic "Page" link (page_id → Page module) or a raw URI/URL. Prefer page links — they survive slug changes; raw URLs are for external links and are the source of most stale-menu bugs after a site restructure.

Nested/tree items. Items carry parent_id and a positional ordering column. When rendering manually (rather than via the module's own view), build the tree in one query and group by parent in PHP rather than recursing per item:

$items = MenuItem::where('menu_id', $menu->id)
    ->where('status', 1)
    ->orderBy('position')
    ->get()
    ->groupBy('parent_id');   // then recurse in the view via $items[0], $items[$parentId]

Multi-language aware links. AsgardCMS is multilingual; if your site is, resolve menu item URLs through the CMS's locale-aware URL resolver rather than concatenating uri strings by hand, or language-switched pages will link back to the default locale.

Seeding menus for a theme. For repeatable deploys, create menus and items in a module seeder (Modules/Menu/Database/Seeders/) using the repositories, keying items by a stable machine name so re-seeding is idempotent (updateOrCreate semantics on the menu name).

Cache the rendered output, not the query. Rendered menus are read-mostly. Cache the final HTML per (menu, locale) key and bust it in the menu/item model's saved/deleted events — cheaper and simpler than patching every query path.

View overriding. Because this is a CMS module, override the module's Blade partials from your theme/module rather than editing Modules/Menu/Resources/views directly; that keeps upgrades (if any) viable.

Gotchas and Tips

  • License is NOASSERTION. Composer reports no recognized license. Before shipping commercially, read the LICENSE file in the repo and get legal sign-off — do not assume MIT because it's Laravel-adjacent.
  • Version lock-in is the real blocker. This is tied to Laravel 5.x and the AsgardCMS module loader. There is no path to Laravel 9/10/11 without a rewrite; treat it as frozen.
  • Abandoned-package risk. 0 stars, 0 dependents, no recent activity. Budget for owning the code: vendor the module into your repo (Modules/Menu/) rather than depending on Packagist, so a repo takedown doesn't break installs.
  • Empty renders are almost always data state, not code: check status/enabled flags, menu_id FK correctness, and position being set (null positions sort unpredictably or drop out of orderBy).
  • N+1 on nested menus. If you render via the built-in helper and see a query per item, eager-load children in the repository or preload in the controller — this is the usual performance culprit on large nav trees.
  • Stale menus after slug edits. Page-linked items re-resolve automatically; URL-typed items do not. Audit for raw uri items before any permalink migration.
  • Blade escaping. The render helper typically returns HTML; use {!! !!} deliberately and make sure titles coming from the CMS are escaped inside the partial to avoid stored-XSS from admin input.
  • Debug the route surface with php artisan route:list | grep menu — backend and frontend menu routes can collide with your own menu route name; namespace yours.
  • Extension points to know: the Menu entity for adding fields (e.g. an icon column), the module's facade for swapping the renderer, and the repository interfaces for custom queries. If you need behavior beyond these, you are editing vendor code — fork first.
  • Prefer the maintained successor if one exists in the AsgardCMS org before committing; this fork is best treated as archival.
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.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo