MoonShine — это админ-панель для Laravel, которая помогает быстро запускать MVP, внутренние кабинеты, CRM и CMS. Ниже — пошаговая инструкция по установке и первичной настройке.
1. Установка
Laravel
Убедитесь, что у вас установлен Laravel 10.48+
. Подробнее в документации Laravel
composer global require laravel/installerlaravel new example-appcd example-app
composer global require laravel/installerlaravel new example-appcd example-app
MoonShine
composer require moonshine/moonshine
composer require moonshine/moonshine
Starter kit
Если у вас уже установлен laravel/installer
, то вы можете установить Laravel + MoonShine одной командой:
laravel new example-app --using=moonshine/app
laravel new example-app --using=moonshine/app
2. Настройка
php artisan moonshine:install -Q
php artisan moonshine:install -Q
Создайте первого администратора. Введите e-mail (логин), имя и пароль — эти данные будут использоваться для входа.
3. Запуск проекта
Запустите локальный сервер:
php artisan serve
php artisan serve
Откройте в браузере: http://127.0.0.1:8000/admin
Войдите под учётной записью администратора.
4. Создание первого ресурса
Сгенерируйте ресурс для модели (например, User
):
php artisan moonshine:resource User
php artisan moonshine:resource User
Готово! Теперь раздел Users
доступен в админке.
http://127.0.0.1:8000/admin/resource/user-resource/index-page
Также вы найдёте его в меню.
5. Добавление полей в ресурс
Раздел добавлен, но если открыть создание записей, то вы увидите пустую страницу без полей формы. Давайте это исправим.
Вот как выглядит новый ресурс сразу после создания:
/*** @extends ModelResource<User>*/class UserResource extends ModelResource{protected string $model = User::class;protected string $title = 'Users';protected function indexFields(): iterable{return [ID::make()->sortable(),];}protected function formFields(): iterable{return [Box::make([ID::make(),]),];}protected function detailFields(): iterable{return [ID::make(),];}protected function rules(mixed $item): array{return [];}}
/*** @extends ModelResource<User>*/class UserResource extends ModelResource{protected string $model = User::class;protected string $title = 'Users';protected function indexFields(): iterable{return [ID::make()->sortable(),];}protected function formFields(): iterable{return [Box::make([ID::make(),]),];}protected function detailFields(): iterable{return [ID::make(),];}protected function rules(mixed $item): array{return [];}}
Изменим заголовок раздела, добавив метод getTitle()
для удобства локализации в будущем:
public function getTitle(): string{return __('Clients');}
public function getTitle(): string{return __('Clients');}
Также рекомендуется указать $column
, чтобы изменить отображаемое поле при связях. Вместо id
укажем email
:
protected string $column = 'email';
protected string $column = 'email';
Теперь добавим поля формы. Используем Text
, Email
, Password
и компоненты для лучшей структуры:
protected function formFields(): iterable{return [Grid::make([Column::make([Box::make('Contact information', [ID::make()->sortable(),Text::make('Name'),Email::make('E-mail', 'email'),]),LineBreak::make(),Box::make('Change password', [Password::make('Password')->customAttributes(['autocomplete' => 'new-password']),PasswordRepeat::make('Password repeat')->customAttributes(['autocomplete' => 'confirm-password']),]),]),]),];}
protected function formFields(): iterable{return [Grid::make([Column::make([Box::make('Contact information', [ID::make()->sortable(),Text::make('Name'),Email::make('E-mail', 'email'),]),LineBreak::make(),Box::make('Change password', [Password::make('Password')->customAttributes(['autocomplete' => 'new-password']),PasswordRepeat::make('Password repeat')->customAttributes(['autocomplete' => 'confirm-password']),]),]),]),];}
Добавим валидацию:
protected function rules(mixed $item): array{return ['name' => 'required','email' => ['sometimes','bail','required','email',Rule::unique('users', 'email')->ignore($item->id),],'password' => !$item->exists? 'required|min:6|required_with:password_repeat|same:password_repeat': 'sometimes|nullable|min:6|required_with:password_repeat|same:password_repeat',];}
protected function rules(mixed $item): array{return ['name' => 'required','email' => ['sometimes','bail','required','email',Rule::unique('users', 'email')->ignore($item->id),],'password' => !$item->exists? 'required|min:6|required_with:password_repeat|same:password_repeat': 'sometimes|nullable|min:6|required_with:password_repeat|same:password_repeat',];}
6. Фильтрация записей
Добавим фильтр по email:
protected function filters(): iterable{return [Text::make('E-mail', 'email')->onApply(fn(Builder $query, ?string $value) => $value === null ? $query : $query->whereLike('email', "%$value%")),];}
protected function filters(): iterable{return [Text::make('E-mail', 'email')->onApply(fn(Builder $query, ?string $value) => $value === null ? $query : $query->whereLike('email', "%$value%")),];}
7. Брендирование
Настроим логотип и цветовую схему в App\Providers\MoonShineServiceProvider.php
:
$config->logo('/images/logo.png')->logo('/images/logo-mini.png', small: true);$colors->primary('#2563EB')->secondary('#93C5FD');
$config->logo('/images/logo.png')->logo('/images/logo-mini.png', small: true);$colors->primary('#2563EB')->secondary('#93C5FD');
8. Локализация
Настройка локализации в config/moonshine.php
:
'locale' => 'ru','locales' => ['en','ru'],
'locale' => 'ru','locales' => ['en','ru'],
Языковые файлы должны находиться в
/lang/vendor/moonshine
. Их можно найти в разделе Плагины или сделать самостоятельно.
9. Документация
Мы установили MoonShine, настроили ресурс, добавили поля, фильтры, брендирование и локализацию.
Рекомендуем изучить документацию, рецепты и видео-гайды, чтобы использовать все возможности платформы.
Важные разделы:
Спасибо, что выбрали MoonShine!