PHP code example of syriable / filament-menu-builder

1. Go to this page and download the library: Download syriable/filament-menu-builder library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

syriable / filament-menu-builder example snippets


$menu = Menu::build('header'); // Collection of ResolvedMenuItem

use Syriable\Filament\Plugins\MenuBuilder\MenuBuilderPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        // ...
        ->plugin(
            MenuBuilderPlugin::make()
                ->navigationGroup('Content')   // optional
                ->navigationSort(10)           // optional
                ->navigationIcon('heroicon-o-bars-3') // optional
                ->navigationLabel('Menus')     // optional
                ->navigation(true)             // set to false to hide the navigation item
                ->locales(['en', 'ar'])        // optional, overrides config('menu-builder.locales')
                ->slideOver(true)              // optional, overrides config('menu-builder.item_form.slide_over')
                ->modalWidth('2xl'),           // optional, overrides config('menu-builder.item_form.width')
        );
}

MenuBuilderPlugin::make()->cluster(\App\Filament\Clusters\Settings::class)

MenuBuilderPlugin::make()->resource(\App\Filament\Resources\PageResource::class)

MenuBuilderPlugin::make()->navigationParentItem('Content')->navigationGroup('Website')

'item_form' => [
    'slide_over' => true, // false: a centered modal
    'width' => '2xl',     // xs, sm, md, lg, xl, 2xl, 3xl, 4xl, 5xl, 6xl, 7xl, full or screen
],

use Syriable\Filament\Plugins\MenuBuilder\Facades\Menu;
use Syriable\Filament\Plugins\MenuBuilder\MenuPlacement;

public function boot(): void
{
    Menu::registerPlacement(
        MenuPlacement::make('header')
            ->label('Header')
            ->icon('heroicon-o-bars-3'),

        MenuPlacement::make('footer')
            ->label('Footer')
            ->description('Links at the bottom of every page')
            ->icon('heroicon-o-rectangle-group')
            ->maxDepth(2)
            ->rootItemTypes(['heading'])        // only headings at the top level
            ->childItemTypes('heading', ['link']) // headings contain links
            ->childItemTypes('link', []),       // links have no children

        MenuPlacement::make('sidebar')
            ->label('Sidebar')
            ->maxDepth(3)
            ->sort(30),
    );
}

'placements' => [
    'header' => ['label' => 'Header', 'icon' => 'heroicon-o-bars-3'],
    'footer' => [
        'label' => 'Footer',
        'max_depth' => 2,
        'root_item_types' => ['heading'],
        'child_item_types' => ['heading' => ['link'], 'link' => []],
    ],
],

['link_type' => 'url', 'url' => '/pricing', 'new_tab' => false]
['link_type' => 'route', 'route' => 'users.show', 'route_parameters' => ['user' => 123]]

['type' => 'link', 'label' => 'Logout', 'visibility' => 'authenticated', 'data' => [
    'link_type' => 'route',
    'route' => 'logout',
    'method' => 'POST',
]],
['type' => 'button', 'label' => 'Delete account', 'color' => 'danger', 'data' => [
    'url' => '/account',
    'method' => 'DELETE',
]],

use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Http\Request;

Menu::registerUrlParameter('team', fn (?Authenticatable $user, ?string $path): ?string => match ($path) {
    'slug' => $user?->currentTeam?->slug,  // {team.slug}
    default => $user?->currentTeam?->id,   // {team}
});

Menu::registerUrlParameter('locale', fn (Request $request): string => app()->getLocale()); // {locale}

['type' => 'link', 'label' => 'My profile', 'visibility' => 'authenticated', 'data' => [
    'link_type' => 'route',
    'route' => 'users.show',
    'route_parameters' => ['user' => '{user}'],
]],

use Filament\Forms\Components\TextInput;
use Syriable\Filament\Plugins\MenuBuilder\MenuItemType;

Menu::registerItemType(
    MenuItemType::make('page')
        ->label('Page')
        ->icon('heroicon-o-document')
        ->schema([                        // Filament components, bound to `data`
            TextInput::make('slug')->

MenuItemType::make('divider')
    ->withoutUrl()               // not a link, like the built-in heading
    ->canHaveChildren(false);    // never allows child items, in any placement

MenuItemType::make('cta')->renderAs(RenderAs::Button)->resolveUrlUsing(fn () => route('register'));

use App\Models\Category;

Menu::registerItemType(
    MenuItemType::make('category')
        ->label('Category')
        ->icon('heroicon-o-tag')
        ->model(
            Category::class,
            titleAttribute: 'name', // used for search and as the default label
            modifyQueryUsing: fn ($query) => $query->where('is_public', true), // optional
        )
        ->resolveUrlUsing(fn (Category $record): string => route('categories.show', $record)),
);

['type' => 'link', 'label' => 'Profile', 'icon' => 'heroicon-m-user', 'data' => [...]],

use Syriable\Filament\Plugins\MenuBuilder\MenuVisibility;

Menu::registerVisibility(
    MenuVisibility::make('admins', 'Administrators', fn (?Authenticatable $user) => $user?->is_admin === true),
);

['type' => 'link', 'label' => 'Download the app', 'data' => [
    'link_type' => 'url',
    'url' => '/app',
    'screens' => ['until' => 'md'],              // phones only
]],
['type' => 'button', 'label' => 'Sign up', 'data' => [
    'url' => '/register',
    'screens' => ['from' => 'md'],               // tablets and larger
]],

use Syriable\Filament\Plugins\MenuBuilder\Facades\Menu;

$items = Menu::build('header');                  // current user and current URL
$items = Menu::build('header', $user);           // a specific user
$items = Menu::build('header', currentUrl: $url);
$items = Menu::build('header', locale: 'ar');   // labels in another locale (default: app()->getLocale())

use Syriable\Filament\Plugins\MenuBuilder\MegaMenu;

public function boot(): void
{
    MegaMenu::register(); // placement "categories"
}

MegaMenu::register('services', fn (MenuPlacement $placement) => $placement
    ->label('Service categories')
    ->childItemTypes('heading', ['link', 'category']));   // also allow a model-backed type in groups

Menu::sync('categories', [
    ['type' => 'mega-category', 'label' => 'Design', 'data' => [
        'link_type' => 'url', 'url' => '/design', 'columns' => 3,
    ], 'children' => [
        ['type' => 'heading', 'label' => 'Logo & Brand', 'children' => [
            ['type' => 'link', 'label' => 'Logo Design', 'badge' => 'New', 'data' => ['link_type' => 'url', 'url' => '/design/logo']],
        ]],
        ['type' => 'link', 'label' => 'Web Design', 'data' => ['link_type' => 'url', 'url' => '/design/web'], 'children' => [
            ['type' => 'link', 'label' => 'Landing Pages', 'data' => ['link_type' => 'url', 'url' => '/design/web/landing']],
        ]],
    ]],
]);

use Filament\Support\Colors\Color;
use Filament\Support\Facades\FilamentColor;

FilamentColor::register([
    'primary' => Color::Amber,
    'gray' => Color::Zinc,
    'info' => Color::Blue,
    'success' => Color::Green,
    'warning' => Color::Orange,
    'danger' => Color::Red,
]);

['type' => 'button', 'label' => 'Login', 'color' => 'gray', 'icon' => 'heroicon-o-user', 'data' => [
    'size' => 'sm',
    'outlined' => true,
    'attributes' => ['x-on:click' => "\$dispatch('open-modal', { id: 'login' })"],
]]

'locales' => [
    'en' => 'English',
    'ar' => 'العربية',
],
// or simply: 'locales' => ['en', 'ar'],

Menu::build('header');               // current locale
Menu::build('header', locale: 'ar'); // Arabic labels

['type' => 'link', 'label' => 'Pricing', 'data' => [
    'link_type' => 'url',
    'url' => '/pricing',
    'label_translations' => ['ar' => 'الأسعار', 'de' => 'Preise'],
]]

Menu::sync('footer', [
    ['type' => 'heading', 'label' => 'Company', 'children' => [
        ['type' => 'link', 'label' => 'About', 'data' => ['link_type' => 'route', 'route' => 'about']],
        ['type' => 'link', 'label' => 'Jobs', 'data' => ['link_type' => 'url', 'url' => '/jobs']],
    ]],
]);

use Syriable\Filament\Plugins\MenuBuilder\Actions\{CreateMenuItem, UpdateMenuItem, MoveMenuItem, ReorderMenuItems, DeleteMenuItem};

$services = app(CreateMenuItem::class)->handle('header', [
    'type' => 'link', 'label' => 'Services', 'data' => ['link_type' => 'url', 'url' => '/services'],
]);
$design = app(CreateMenuItem::class)->handle('header', [...], parent: $services);

app(UpdateMenuItem::class)->handle($design, ['badge' => 'New']);
app(MoveMenuItem::class)->handle($design, parent: null, position: 0);   // to the root, first
app(ReorderMenuItems::class)->handle('header', parent: null, orderedIds: [3, 1, 2]);
app(DeleteMenuItem::class)->handle($services); // deletes the subtree, returns the count

use Syriable\Filament\Plugins\MenuBuilder\Models\MenuItem;

Gate::policy(MenuItem::class, MenuItemPolicy::class);

class MenuItemPolicy
{
    public function viewAny(User $user, string $placement): bool { return $user->can('manage menus'); }
    public function create(User $user, string $placement): bool  { /* ... */ }
    public function update(User $user, string $placement): bool  { /* ... */ }
    public function reorder(User $user, string $placement): bool { /* ... */ }
    public function delete(User $user, string $placement): bool  { /* ... */ }
    public function publish(User $user, string $placement): bool { /* ... */ } // Save changes
}

MenuBuilderPlugin::make()->shield(false); // never check Shield permissions
MenuBuilderPlugin::make()->shield();      // always check them

'cache' => [
    'enabled' => env('MENU_BUILDER_CACHE', true),
    'store' => null,      // cache store, null = default
    'prefix' => 'menu-builder',
    'ttl' => null,        // seconds, null = until the next save
],

'model' => App\Models\MenuItem::class,   // must extend the package model
'table_name' => 'menu_items',
bash
php artisan menu-builder:install
bash
php artisan filament:assets
bash
php artisan vendor:publish --tag="menu-builder-config"
php artisan vendor:publish --tag="menu-builder-migrations"
php artisan migrate
bash
php artisan filament:assets
blade
<html dir="{{ __('filament-panels::layout.direction') }}">
…
<x-menu-builder::header :items="Menu::build('header')" direction="rtl" />
bash
   php artisan vendor:publish --tag="menu-builder-views"
   # resources/views/vendor/menu-builder/components/item.blade.php
   
blade
   {{-- resources/views/components/nav-item.blade.php --}}
   @props(['item', 'level' => 1, 'headingTag' => 'span', 'trigger' => false])

   <x-filament::link
       :tag="$trigger ? 'button' : 'a'"
       :href="$trigger ? null : $item->url"
       :attributes="$item->itemAttributes()->class('nav-link')"
   >{{ $item->label }}</x-filament::link>