Меню

# Основы

Настройка навигационного меню осуществляется в App\Providers\MoonShineServiceProvider через метод menu(), который возвращает массив элементов меню.

Для того чтобы добавить пункт меню, необходимо воспользоваться классом MoonShine\Menu\MenuItem и его статическим методом make().

MenuItem::make(Closure|string $label, Closure|MenuFiller|string $filler, null|string $icon = null, Closure|bool $blank = false)
  • $label - название пункта меню,
  • $filler - элемент для формирования url,
  • $icon - иконка для пункта меню,
  • $blank - открыть в новой вкладке.

В качестве второго параметра можно передать ModelResource , Page или Resource.

namespace App\Providers;
 
use MoonShine\Menu\MenuItem;
use MoonShine\Providers\MoonShineApplicationServiceProvider;
use MoonShine\Resources\MoonShineUserResource;
 
class MoonShineServiceProvider extends MoonShineApplicationServiceProvider
{
protected function menu(): array
{
return [
MenuItem::make('Admins', new MoonShineUserResource()),
MenuItem::make('Home', fn() => route('home')),
MenuItem::make('Docs', 'https://moonshine-laravel.com/docs'),
MenuItem::make('Laravel Docs', 'https://laravel.com/docs', blank: true)
];
}
 
//...
}

Если меню создается для ModelResource или Resource, то для элемента меню будет использоваться первая страница объявленная в методе pages().

Меню через Closure

Объявить меню можно используя замыкание на основе текущего запроса:

namespace App\Providers;
 
use Closure;
use MoonShine\MoonShineRequest;
use MoonShine\Providers\MoonShineApplicationServiceProvider;
 
class MoonShineServiceProvider extends MoonShineApplicationServiceProvider
{
protected function menu(): Closure
{
return static function (MoonShineRequest $request) {
return [
//...
];
};
};
 
//...
}

Будет полезно если вы решили использовать multi tenancy или же у вас и веб и админ часть реализована на MoonShine.

При объявлении меню через Closure, необходимо вручную зарегистрировать страницы и ресурсы в соответствующих методах.

# Группы

Пункты меню можно объединять в группы. Для этого используется класс MoonShine\Menu\MenuGroup со статическим методом make().

MenuGroup::make(Closure|string $label, iterable $items, null|string $icon = null)
  • $label - название группы,
  • $items - массив компонентов меню,
  • $icon - иконка для группы.
namespace App\Providers;
 
use MoonShine\Menu\MenuGroup;
use MoonShine\Menu\MenuItem;
use MoonShine\Providers\MoonShineApplicationServiceProvider;
use MoonShine\Resources\MoonShineUserResource;
use MoonShine\Resources\MoonShineUserRoleResource;
 
class MoonShineServiceProvider extends MoonShineApplicationServiceProvider
{
protected function menu(): array
{
return [
MenuGroup::make('System', [
MenuItem::make('Admins', new MoonShineUserResource()),
MenuItem::make('Roles', new MoonShineUserRoleResource()),
])
];
}
 
//...
}

Так же группе можно добавить элементы через метод setItems()

setItems(iterable $items)
namespace App\Providers;
 
use MoonShine\Menu\MenuGroup;
use MoonShine\Menu\MenuItem;
use MoonShine\Providers\MoonShineApplicationServiceProvider;
use MoonShine\Resources\MoonShineUserResource;
use MoonShine\Resources\MoonShineUserRoleResource;
 
class MoonShineServiceProvider extends MoonShineApplicationServiceProvider
{
protected function menu(): array
{
return [
MenuGroup::make('System')->setItems([
MenuItem::make('Admins', new MoonShineUserResource()),
MenuItem::make('Roles', new MoonShineUserRoleResource()),
])
];
}
 
//...
}

# Разделитель

Пункты меню можно визуально разделить с помощью MoonShine\Menu\MenuDivider.

MenuDivider::make(Closure|string $label = '')
namespace App\Providers;
 
use App\MoonShine\Resources\ArticleResource;
use App\MoonShine\Resources\CategoryResource;
use MoonShine\Menu\MenuDivider;
use MoonShine\Menu\MenuItem;
use MoonShine\Providers\MoonShineApplicationServiceProvider;
 
class MoonShineServiceProvider extends MoonShineApplicationServiceProvider
{
protected function menu(): array
{
return [
MenuItem::make('Admins', new MoonShineUserResource()),
MenuDivider::make(),
MenuItem::make('Roles', new MoonShineUserRoleResource()),
];
}
 
//...
}

В качестве разделителя можно использовать текст, для этого его нужно передать методу make().

namespace App\Providers;
 
use App\MoonShine\Resources\ArticleResource;
use App\MoonShine\Resources\CategoryResource;
use MoonShine\Menu\MenuDivider;
use MoonShine\Menu\MenuItem;
use MoonShine\Providers\MoonShineApplicationServiceProvider;
 
class MoonShineServiceProvider extends MoonShineApplicationServiceProvider
{
protected function menu(): array
{
return [
MenuItem::make('Admins', new MoonShineUserResource()),
MenuDivider::make('Divider'),
MenuItem::make('Roles', new MoonShineUserRoleResource()),
];
}
 
//...
}

# Условие отображения

Отображать элементы меню можно по условию, воспользовавшись методом canSee().

canSee(Closure $callback)
namespace App\Providers;
 
use MoonShine\Menu\MenuGroup;
use MoonShine\Menu\MenuItem;
use MoonShine\Providers\MoonShineApplicationServiceProvider;
use MoonShine\Resources\MoonShineUserResource;
use MoonShine\Resources\MoonShineUserRoleResource;
 
class MoonShineServiceProvider extends MoonShineApplicationServiceProvider
{
protected function menu(): array
{
return [
MenuGroup::make('System',
MenuItem::make('Admins', new MoonShineUserResource()),
MenuItem::make('Roles', new MoonShineUserRoleResource())
->canSee(fn()=> false), [
])
->canSee(function(Request $request) {
return $request->user('moonshine')?->id === 1;
})
];
}
 
//...
}

# Иконка

У пункта меню и у группы можно задать иконку. Это можно реализовать несколькими методами.

Через параметр

Иконку можно задать, передав третьим параметром название в статическом методе make().

namespace App\Providers;
 
use MoonShine\Menu\MenuGroup;
use MoonShine\Menu\MenuItem;
use MoonShine\Providers\MoonShineApplicationServiceProvider;
use MoonShine\Resources\MoonShineUserResource;
use MoonShine\Resources\MoonShineUserRoleResource;
 
class MoonShineServiceProvider extends MoonShineApplicationServiceProvider
{
protected function menu(): array
{
return [
MenuGroup::make('System', [
MenuItem::make('Admins', new MoonShineUserResource(), 'heroicons.outline.users'),
MenuItem::make('Roles', new MoonShineUserRoleResource(), 'heroicons.hashtag'),
])
];
}
 
//...
}
Через метод

Воспользоваться методом icon().

icon(string $icon)
namespace App\Providers;
 
use MoonShine\Menu\MenuGroup;
use MoonShine\Menu\MenuItem;
use MoonShine\Providers\MoonShineApplicationServiceProvider;
use MoonShine\Resources\MoonShineUserResource;
use MoonShine\Resources\MoonShineUserRoleResource;
 
class MoonShineServiceProvider extends MoonShineApplicationServiceProvider
{
protected function menu(): array
{
return [
MenuGroup::make('System', [
MenuItem::make('Admins', new MoonShineUserResource())
->icon('heroicons.outline.users'),
MenuItem::make('Roles', new MoonShineUserRoleResource())
->icon('heroicons.hashtag'),
])
->icon('heroicons.cog')
];
}
 
//...
}
Через атрибут

У пункта меню отобразится иконка, если у класса ModelResource , Page или Resource задан атрибут Icon и иконка не переопределена другими способами.

namespace MoonShine\Resources;
 
#[Icon('heroicons.outline.users')]
class MoonShineUserResource extends ModelResource
{
 
//...
 
}

За более подробной информацией обратитесь к разделу Icons .

# Метка

Также есть возможность добавить значок к пункту меню или группе.

Через элемент меню

Для добавления значка к пункту меню или группе используется метод badge(), который в качестве параметра принимает замыкание.

badge(Closure $callback)
namespace App\Providers;
 
use App\Models\Comment;
use App\MoonShine\Resources\CommentResource;
use MoonShine\Menu\MenuItem;
use MoonShine\Providers\MoonShineApplicationServiceProvider;
 
class MoonShineServiceProvider extends MoonShineApplicationServiceProvider
{
protected function menu(): array
{
return [
MenuItem::make('Comments', new CommentResource())
->badge(fn() => Comment::count())
];
}
 
//...
}
Через метод класса

Для ModelResource , Page или Resource существует альтернативный способ задать значок - метод getBadge().

namespace App\MoonShine\Resources;
 
use App\Models\Post;
use MoonShine\Resources\ModelResource;
 
class PostResource extends ModelResource
{
//...
 
public function getBadge(): string
{
return 'new';
}
 
//...
}

# Перевод

Для перевода пунктов меню необходимо в качестве названия передать ключ перевода и добавить метод translatable()

translatable(string $key = '')
namespace App\Providers;
 
use App\Models\Comment;
use App\MoonShine\Resources\CommentResource;
use MoonShine\Menu\MenuItem;
use MoonShine\Providers\MoonShineApplicationServiceProvider;
 
class MoonShineServiceProvider extends MoonShineApplicationServiceProvider
{
protected function menu(): array
{
return [
MenuItem::make('menu.Comments', new CommentResource())
->translatable()
// or
MenuItem::make('Comments', new CommentResource())
->translatable('menu')
];
}
 
//...
}
// lang/ru/menu.php
 
return [
'Comments' => 'Комментарии',
];

Для перевода меток меню можно воспользоваться средствами перевода Laravel.

namespace App\Providers;
 
use App\Models\Comment;
use App\MoonShine\Resources\CommentResource;
use MoonShine\Menu\MenuItem;
use MoonShine\Providers\MoonShineApplicationServiceProvider;
 
class MoonShineServiceProvider extends MoonShineApplicationServiceProvider
{
protected function menu(): array
{
return [
MenuItem::make('Comments', new CommentResource())
->badge(fn() => __('menu.badge.new'))
];
}
 
//...
}

# Открытие в новой вкладке

У пункта меню можно указать флаг, указывающий, открывать ссылку в новой вкладке или нет. Это можно реализовать несколькими способами.

Через параметр

Флаг можно задать, передав четвёртым параметром true/false или замыкание в статическом методе make().

namespace App\Providers;
 
use MoonShine\Menu\MenuGroup;
use MoonShine\Menu\MenuItem;
use MoonShine\Providers\MoonShineApplicationServiceProvider;
 
class MoonShineServiceProvider extends MoonShineApplicationServiceProvider
{
protected function menu(): array
{
return [
MenuGroup::make('System', [
MenuItem::make('MoonShine Docs', 'https://moonshine-laravel.com/docs', 'heroicons.arrow-up', true),
MenuItem::make('Laravel Docs', 'https://laravel.com/docs', 'heroicons.arrow-up', fn() => true),
])
];
}
 
//...
}
Через метод

Воспользоваться методом blank().

blank(Closure|bool $blankCondition = true)
namespace App\Providers;
 
use MoonShine\Menu\MenuItem;
use MoonShine\Providers\MoonShineApplicationServiceProvider;
 
class MoonShineServiceProvider extends MoonShineApplicationServiceProvider
{
protected function menu(): array
{
return [
MenuItem::make('MoonShine Docs', 'https://moonshine-laravel.com/docs')
->blank(),
MenuItem::make('Laravel Docs', 'https://laravel.com/docs')
->blank(fn() => true),
];
}
 
//...
}

# Активный пункт

Пункт меню становится активным если он соответствует url, но метод forceActive() позволяет принудительно сделать пункт активным.

forceActive(Closure|bool $forceActive)
namespace App\Providers;
 
use MoonShine\Menu\MenuItem;
use MoonShine\Providers\MoonShineApplicationServiceProvider;
 
class MoonShineServiceProvider extends MoonShineApplicationServiceProvider
{
protected function menu(): array
{
return [
MenuItem::make('Label', '/endpoint')
->forceActive(fn() => request()->fullUrlIs('*admin/endpoint/*')),
];
}
 
//...
}