Advanced hierarchical menu management tool for Laravel Nova with drag-and-drop interface, temporal visibility, and resource integration
skylark-team/nova-menus is a Laravel package for advanced hierarchical menu management tool for laravel nova with drag-and-drop interface, temporal visibility, and resource integration.
It currently has 2 GitHub stars and 0 downloads on Packagist.
Install it with composer require skylark-team/nova-menus.
Discover more Laravel packages by skylark-team
or browse all Laravel packages to compare alternatives.
Last updated
Advanced hierarchical menu management tool for Laravel Nova with intuitive drag-and-drop interface, temporal visibility, resource integration, and comprehensive testing.
Main menu management interface with Nova integration
Menu item management with hierarchical structure and edit controls
You can install the package via Composer:
composer require skylark-team/nova-menus
After installation, publish and run the migrations:
php artisan vendor:publish --tag="menus-migrations"
php artisan migrate
Optionally, you can publish the config file:
php artisan vendor:publish --tag="menus-config"
Register the tool in your NovaServiceProvider:
use Skylark\Menus\MenusTool;
public function tools()
{
return [
new MenusTool(),
];
}
use Skylark\Menus\Models\MenuItem;
// Create a root menu
$menu = MenuItem::create([
'name' => 'Main Navigation',
'slug' => 'main-nav',
'is_root' => true,
'max_depth' => 6,
]);
// Add menu items
$homeItem = MenuItem::create([
'menu_id' => $menu->id,
'name' => 'Home',
'custom_url' => '/',
'position' => 1,
]);
$aboutItem = MenuItem::create([
'menu_id' => $menu->id,
'name' => 'About',
'custom_url' => '/about',
'position' => 2,
]);
// Get a menu with all items
$menu = MenuItem::where('slug', 'main-nav')->first();
$items = $menu->children()->visible()->ordered()->get();
// Get hierarchical structure
$tree = MenuItem::where('menu_id', $menu->id)
->with('children.children')
->whereNull('parent_id')
->ordered()
->get();
use Carbon\Carbon;
// Get currently visible items
$visibleItems = MenuItem::visible()->get();
// Get items visible at specific time
$futureDate = Carbon::parse('2024-12-25 00:00:00');
$christmasItems = MenuItem::isVisibleAt($futureDate)->get();
// Create scheduled item
MenuItem::create([
'name' => 'Holiday Special',
'custom_url' => '/holiday',
'display_at' => '2024-12-01 00:00:00',
'hide_at' => '2024-12-31 23:59:59',
]);
@php
$menu = \Skylark\Menus\Models\MenuItem::where('slug', 'main-nav')->first();
$items = $menu ? $menu->children()->visible()->ordered()->get() : collect();
@endphp
<nav class="main-navigation">
@foreach ($items as $item)
<a href="{{ $item->getUrl() }}"
class="nav-item {{ $item->isCurrentPage() ? 'active' : '' }}">
{{ $item->name }}
</a>
@if ($item->children->isNotEmpty())
<ul class="nav-submenu">
@foreach ($item->children as $child)
<li>
<a href="{{ $child->getUrl() }}">{{ $child->name }}</a>
</li>
@endforeach
</ul>
@endif
@endforeach
</nav>
// In your controller
public function getMenu($slug)
{
$menu = MenuItem::where('slug', $slug)->first();
if (!$menu) {
return response()->json(['error' => 'Menu not found'], 404);
}
$tree = $menu->children()
->visible()
->with(['children' => function ($query) {
$query->visible()->ordered();
}])
->ordered()
->get();
return response()->json($tree);
}
The config file allows you to customize various aspects of the menu system:
return [
// Maximum nesting depth
'max_depth' => 10,
// Performance monitoring
'performance_monitoring' => env('MENUS_PERFORMANCE_MONITORING', false),
'slow_query_threshold' => 100, // milliseconds
'log_slow_queries' => env('MENUS_LOG_SLOW_QUERIES', false),
// Resource integration
'resources' => [
'App\\Models\\Page' => [
'model' => 'App\\Models\\Page',
'name_field' => 'title',
'slug_field' => 'slug',
'route_pattern' => '/pages/{slug}',
],
// Add more resource types...
],
// Cache settings
'cache' => [
'enabled' => true,
'ttl' => 3600, // 1 hour
'key_prefix' => 'menus',
],
];
The package includes performance monitoring tools:
# Analyze query performance
php artisan menus:analyze-performance
# Generate optimization recommendations
php artisan menus:analyze-performance --threshold=50 --export=performance-report.json
For optimal performance, ensure these indexes exist:
-- Basic indexes
CREATE INDEX idx_menu_items_menu_id ON menu_items(menu_id);
CREATE INDEX idx_menu_items_parent_id ON menu_items(parent_id);
CREATE INDEX idx_menu_items_position ON menu_items(position);
-- Composite indexes for better performance
CREATE INDEX idx_menu_items_menu_parent ON menu_items(menu_id, parent_id);
CREATE INDEX idx_menu_items_parent_position ON menu_items(parent_id, position);
CREATE INDEX idx_menu_items_visibility ON menu_items(is_active, display_at, hide_at);
-- Nested set indexes (if using nested set model)
CREATE INDEX idx_menu_items_lft_rgt ON menu_items(lft, rgt);
Enable caching for frequently accessed menus:
use Skylark\Menus\Models\MenuItem;
// Cache menu for 1 hour
$menu = Cache::remember("menu.{$slug}", 3600, function () use ($slug) {
return MenuItem::where('slug', $slug)
->with(['children' => function ($query) {
$query->visible()->ordered();
}])
->first();
});
The package includes comprehensive tests covering unit, integration, and end-to-end scenarios:
# Run all tests
composer test
# Run with coverage
composer test-coverage
# Run specific test types
vendor/bin/pest tests/Unit
vendor/bin/pest tests/Feature
vendor/bin/pest tests/Performance
# Run E2E tests with Playwright
npm run test:e2e
# Clone the repository
git clone https://github.com/skylark-team/nova-menus.git
cd nova-menus
# Install dependencies
composer install
npm install
# Set up testing environment
cp .env.example .env
php artisan key:generate
php artisan migrate --database=testing
# Run development server
composer run dev
# Format code
composer format
# Check code style
composer lint
# Run static analysis
composer analyse
# Run all quality checks
composer test && composer lint && composer analyse
// Hierarchy methods
$item->children() // Get direct children
$item->descendants // Get all descendants
$item->ancestors // Get all ancestors
$item->siblings() // Get siblings
// Visibility methods
MenuItem::visible() // Scope for visible items
MenuItem::isVisibleAt($date) // Scope for items visible at date
$item->isCurrentlyVisible() // Check if item is visible now
// Utility methods
$item->getUrl() // Get the item URL
$item->isCurrentPage() // Check if item matches current page
$item->hasChildren() // Check if item has children
use Skylark\Menus\Services\QueryPerformanceMonitor;
$monitor = new QueryPerformanceMonitor();
// Monitor specific operation
$stats = $monitor->monitor(function () {
return MenuItem::with('children')->get();
});
// Get optimization suggestions
$suggestions = $monitor->getMenuOptimizationSuggestions();
Please see CONTRIBUTING.md for details.
Please review our security policy on how to report security vulnerabilities.
Please see CHANGELOG.md for more information on what has changed recently.
The MIT License (MIT). Please see License File for more information.
If you discover any issues or have questions, please:
For commercial support, please contact us at [email protected].