notebrainslab/filament-menu-manager
Installation:
composer require notebrainslab/filament-menu-manager
php artisan filament-menu-manager:install
Run migrations to create the menu_items and menu_locations tables.
Register the Plugin:
Add to app/Providers/Filament/AdminPanelProvider.php (or app/Providers/FilamentPanelProvider.php for Filament v5):
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
\Notebrainslab\FilamentMenuManager\FilamentMenuManagerPlugin::make(),
]);
}
First Use Case:
Access the plugin via the Filament admin panel (default URL: /admin/menu-manager). Create a new location (e.g., "Primary Navigation") and add menu items via:
Post, Page) by configuring a source.Defining Menu Locations: Locations are created in the plugin UI but can be pre-configured via a seed:
// database/seeders/MenuManagerSeeder.php
use Notebrainslab\FilamentMenuManager\Models\MenuLocation;
public function run()
{
MenuLocation::create(['name' => 'Primary Navigation']);
MenuLocation::create(['name' => 'Footer Links']);
}
Adding Eloquent Model Sources:
Register a model as a menu item source in config/filament-menu-manager.php:
'sources' => [
'posts' => [
'model' => \App\Models\Post::class,
'label' => 'Posts',
'url' => fn ($record) => route('posts.show', $record),
'icon' => 'heroicon-o-document-text',
],
],
Access the source in the plugin UI under "Add Item" > "Eloquent Sources".
Dynamic Menu Rendering: Fetch menu items for a location in a Blade view or Livewire component:
use Notebrainslab\FilamentMenuManager\Facades\MenuManager;
$primaryMenu = MenuManager::getMenu('Primary Navigation');
Render with:
<ul>
@foreach($primaryMenu as $item)
<li><a href="{{ $item->url }}">{{ $item->title }}</a></li>
@endforeach
</ul>
Customizing Item Display:
Extend the MenuItem model or use a custom view for rendering:
// app/Providers/AppServiceProvider.php
public function boot()
{
\Notebrainslab\FilamentMenuManager\MenuManager::macro('renderItem', function ($item) {
return view('custom.menu-item', compact('item'));
});
}
Integration with Filament Pages:
Use the MenuManager facade to inject menus into Filament resources/pages:
use Notebrainslab\FilamentMenuManager\Facades\MenuManager;
public static function getNavigationItems(): array
{
return MenuManager::getMenu('Sidebar')->toArray();
}
Conditional Menu Items: Filter menu items based on user roles or other logic:
$menu = MenuManager::getMenu('Primary Navigation')
->where('visible_to', auth()->user()->role);
Real-Time Updates: Leverage Livewire to update menus dynamically:
public function updatedMenu()
{
$this->emit('menuUpdated');
}
Listen in JavaScript:
Livewire.on('menuUpdated', () => {
location.reload(); // Or fetch updated menu via AJAX
});
Multi-Language Support:
Use Laravel localization with a custom title attribute:
'sources' => [
'pages' => [
'model' => \App\Models\Page::class,
'title' => fn ($record) => __($record->title),
],
],
API Access: Expose menu endpoints via Laravel routes:
Route::get('/api/menus/{location}', function ($location) {
return MenuManager::getMenu($location);
});
Migration Conflicts:
menu_items table already exists, manually merge columns or reset migrations.php artisan migrate:fresh --env=testing
SortableJS Conflicts:
@filamentScripts
@stack('filament-menu-manager-scripts')
Auto-Save Delays:
config/filament-menu-manager.php:
'auto_save_debounce' => 200, // Milliseconds
Eloquent Source Caching:
url and title closures are lazy-loaded:
'url' => fn ($record) => route('posts.show', $record, false), // Disable cache
Permission Issues:
view menu manager permission will see a 403 error.User resource or middleware:
public function authorizeAccess(): void
{
$this->authorize('view menu manager');
}
Log Menu Queries:
Enable query logging in AppServiceProvider:
public function boot()
{
if (app()->environment('local')) {
\DB::enableQueryLog();
}
}
Dump queries after fetching a menu:
$menu = MenuManager::getMenu('Primary Navigation');
\Log::info(\DB::getQueryLog());
Check Plugin Assets:
php artisan filament:cache-reset
php artisan view:clear
Validate Menu Locations: Ensure locations exist before rendering:
if (!MenuManager::hasLocation('Primary Navigation')) {
abort(404);
}
Custom Menu Item Types:
Extend the MenuItem model or create a trait:
namespace App\Models;
use Notebrainslab\FilamentMenuManager\Models\MenuItem;
class CustomMenuItem extends MenuItem
{
public function getCustomAttribute()
{
return $this->attributes['custom_data'] ?? null;
}
}
Override Default Views: Publish and modify views:
php artisan vendor:publish --tag="filament-menu-manager-views"
Override resources/views/vendor/filament-menu-manager/....
Add Custom Fields:
Extend the MenuItem form using Filament’s FormBuilder:
use Notebrainslab\FilamentMenuManager\Forms\Components\MenuItemForm;
MenuItemForm::modify(function (MenuItemForm $form) {
$form->addComponents([
TextInput::make('custom_field')
->columnSpanFull(),
]);
});
Hook into Menu Events: Listen for item creation/updates:
// app/Providers/EventServiceProvider.php
protected $listen = [
\Notebrainslab\FilamentMenuManager\Events\MenuItemSaved::class => [
\App\Listeners\LogMenuChanges::class,
],
];
Dark Mode Customization: Override CSS variables in your app’s stylesheet:
:root {
--filament-menu-manager-bg: #1a1a1a;
--filament-menu-manager-text: #e0e0e0;
}
How can I help you explore Laravel packages today?