- Основы
- Создание страницы
- Заголовок
- Компоненты
- Хлебные крошки
- Шаблон
- Псевдоним
- Рендеринг
- Перед рендерингом
- Модификатор ответа
- Жизненный цикл
- Создание ссылки на страницу в ресурсе
- Assets
Основы
Page
является основой админ-панели MoonShine. Основное назначение Page
- отображение компонентов.
Страницы с одинаковой логикой могут быть объединены в Resource
.
Создание страницы
Для создания класса страницы можно использовать консольную команду:
php artisan moonshine:page
php artisan moonshine:page
После ввода имени класса будет создан файл, который является основой для страницы в админ-панели.
По умолчанию он располагается в директории app/MoonShine/Pages
.
О всех поддерживаемых опциях можно узнать в разделе Команды.
Страницы при выполнении команды автоматически регистрируются в системе, но если вы создаете страницу вручную,
то её необходимо самостоятельно зарегистрировать в MoonShineServiceProvider
в методе $core->pages()
.
Заголовок
Заголовок страницы можно задать через свойство $title
, а подзаголовок — через $subtitle
.
namespace App\MoonShine\Pages;use MoonShine\Laravel\Pages\Page;class CustomPage extends Page{protected string $title = 'CustomPage';protected string $subtitle = 'Подзаголовок';// ...}
namespace App\MoonShine\Pages;use MoonShine\Laravel\Pages\Page;class CustomPage extends Page{protected string $title = 'CustomPage';protected string $subtitle = 'Подзаголовок';// ...}
Если для заголовка и подзаголовка требуется какая-то логика, то методы title()
и subtitle()
позволяют её реализовать.
namespace App\MoonShine\Pages;use MoonShine\Laravel\Pages\Page;class CustomPage extends Page{// ...public function getTitle(): string{return $this->title ?: 'CustomPage';}public function getSubtitle(): string{return $this->subtitle ?: 'Подзаголовок';}}
namespace App\MoonShine\Pages;use MoonShine\Laravel\Pages\Page;class CustomPage extends Page{// ...public function getTitle(): string{return $this->title ?: 'CustomPage';}public function getSubtitle(): string{return $this->subtitle ?: 'Подзаголовок';}}
Компоненты
Для регистрации компонентов страницы используется метод components()
.
namespace App\MoonShine\Pages;use MoonShine\Laravel\Pages\Page;use MoonShine\UI\Components\Layout\Box;use MoonShine\UI\Components\Layout\Column;use MoonShine\UI\Components\Layout\Grid;class CustomPage extends Page{// ...protected function components(): iterable{return [Grid::make([Column::make([Box::make([// ...])])->columnSpan(6),Column::make([Box::make([// ...])])->columnSpan(6),])];}}
namespace App\MoonShine\Pages;use MoonShine\Laravel\Pages\Page;use MoonShine\UI\Components\Layout\Box;use MoonShine\UI\Components\Layout\Column;use MoonShine\UI\Components\Layout\Grid;class CustomPage extends Page{// ...protected function components(): iterable{return [Grid::make([Column::make([Box::make([// ...])])->columnSpan(6),Column::make([Box::make([// ...])])->columnSpan(6),])];}}
Для более подробной информации обратитесь к разделу Компоненты.
Хлебные крошки
За генерацию хлебных крошек отвечает метод getBreadcrumbs()
.
namespace App\MoonShine\Pages;use MoonShine\Laravel\Pages\Page;class CustomPage extends Page{// ...public function getBreadcrumbs(): array{return ['#' => $this->getTitle()];}}
namespace App\MoonShine\Pages;use MoonShine\Laravel\Pages\Page;class CustomPage extends Page{// ...public function getBreadcrumbs(): array{return ['#' => $this->getTitle()];}}
Шаблон
По умолчанию страницы используют шаблон отображения AppLayout
или CompactLayout
.
Подробнее про шаблоны читайте в разделе Layout.
namespace App\MoonShine\Pages;use MoonShine\Laravel\Layouts\AppLayout;use MoonShine\Laravel\Pages\Page;class CustomPage extends Page{protected ?string $layout = AppLayout::class;// ...}
namespace App\MoonShine\Pages;use MoonShine\Laravel\Layouts\AppLayout;use MoonShine\Laravel\Pages\Page;class CustomPage extends Page{protected ?string $layout = AppLayout::class;// ...}
Вы также можете указать шаблон через атрибут.
use MoonShine\Core\Attributes\Layout;use MoonShine\Laravel\Layouts\AppLayout;#[Layout(AppLayout::class)]class CustomPage extends Page
use MoonShine\Core\Attributes\Layout;use MoonShine\Laravel\Layouts\AppLayout;#[Layout(AppLayout::class)]class CustomPage extends Page
Модификация шаблона
При разработке административной панели с использованием MoonShine часто возникает потребность в гибком управлении шаблонами.
Вместо создания множества отдельных шаблонов для различных ситуаций, MoonShine предоставляет возможность динамически модифицировать существующий шаблон.
Это достигается с помощью метода modifyLayout()
.
Метод modifyLayout()
позволяет получить доступ к шаблону после создания его экземпляра и внести в него необходимые изменения.
Это особенно полезно, когда вам нужно адаптировать шаблон под конкретные условия или добавить динамический контент.
Пример использования
Рассмотрим пример из пакета moonshine-software/two-factor
, который демонстрирует, как можно использовать modifyLayout()
для настройки шаблона аутентификации:
use MoonShine\Contracts\UI\LayoutContract;/*** @param LoginLayout $layout*/protected function modifyLayout(LayoutContract $layout): LayoutContract{return $layout->title(__('moonshine-two-factor::ui.2fa'))->description(__('moonshine-two-factor::ui.confirm'));}
use MoonShine\Contracts\UI\LayoutContract;/*** @param LoginLayout $layout*/protected function modifyLayout(LayoutContract $layout): LayoutContract{return $layout->title(__('moonshine-two-factor::ui.2fa'))->description(__('moonshine-two-factor::ui.confirm'));}
Псевдоним
Если необходимо изменить псевдоним страницы, это можно сделать через свойство $alias
.
namespace App\MoonShine\Pages;use MoonShine\Laravel\Pages\Page;class CustomPage extends Page{protected ?string $alias = null;// ...}
namespace App\MoonShine\Pages;use MoonShine\Laravel\Pages\Page;class CustomPage extends Page{protected ?string $alias = null;// ...}
Также можно переопределить метод getAlias()
.
namespace App\MoonShine\Pages;use MoonShine\Laravel\Pages\Page;class CustomPage extends Page{public function getAlias(): ?string{return 'custom_page';}// ...}
namespace App\MoonShine\Pages;use MoonShine\Laravel\Pages\Page;class CustomPage extends Page{public function getAlias(): ?string{return 'custom_page';}// ...}
Рендеринг
Вы можете отображать страницу вне MoonShine, просто вернув её в контроллере.
class ProfileController extends Controller{// ...public function __invoke(ProfilePage $page): ProfilePage{return $page;}}
class ProfileController extends Controller{// ...public function __invoke(ProfilePage $page): ProfilePage{return $page;}}
Или с Fortify
Fortify::loginView(static fn() => app(ProfilePage::class));
Fortify::loginView(static fn() => app(ProfilePage::class));
Перед рендерингом
Метод prepareBeforeRender()
позволяет выполнить какие-либо действия перед отображением страницы.
namespace App\MoonShine\Pages;use MoonShine\Laravel\Pages\Page;class CustomPage extends Page{protected function prepareBeforeRender(): void{parent::prepareBeforeRender();if (auth()->user()->moonshine_user_role_id !== MoonshineUserRole::DEFAULT_ROLE_ID) {abort(403);}}}
namespace App\MoonShine\Pages;use MoonShine\Laravel\Pages\Page;class CustomPage extends Page{protected function prepareBeforeRender(): void{parent::prepareBeforeRender();if (auth()->user()->moonshine_user_role_id !== MoonshineUserRole::DEFAULT_ROLE_ID) {abort(403);}}}
Модификатор ответа
По умолчанию страница рендерится через PageController
, вызывая метод render()
.
Однако иногда возникает необходимость изменить стандартный ответ, например, выполнить редирект при определенных условиях.
В таких случаях можно использовать метод modifyResponse()
.
Метод modifyResponse()
позволяет модифицировать ответ страницы перед его отправкой.
Вот пример его использования:
use Symfony\Component\HttpFoundation\Response;protected function modifyResponse(): ?Response{if (request()->has('id')) {return redirect()->to('/admin/article-resource/index-page');}return null;}
use Symfony\Component\HttpFoundation\Response;protected function modifyResponse(): ?Response{if (request()->has('id')) {return redirect()->to('/admin/article-resource/index-page');}return null;}
Использование modifyResponse()
предоставляет гибкий способ управления ответом страницы, позволяя реализовать сложную логику обработки запросов и ответов в административной панели.
Жизненный цикл
Page
имеет несколько различных методов подключения к различным частям своего жизненного цикла. Давайте пройдемся по ним:
Активная страница
Метод onLoad()
дает возможность интегрироваться в момент когда страница загружена и в данный момент является активной.
namespace App\MoonShine\Pages;use MoonShine\Laravel\Pages\Page;class PostPage extends Page{// ...protected function onLoad(): void{parent::onLoad();// ...}}
namespace App\MoonShine\Pages;use MoonShine\Laravel\Pages\Page;class PostPage extends Page{// ...protected function onLoad(): void{parent::onLoad();// ...}}
Создание экземпляра
Метод booted()
дает возможность интегрироваться в момент, когда MoonShine создает экземпляр страницы в системе.
namespace App\MoonShine\Pages;use MoonShine\Laravel\Pages\Page;class PostPage extends Page{// ...protected function booted(): void{parent::booted();// ...}}
namespace App\MoonShine\Pages;use MoonShine\Laravel\Pages\Page;class PostPage extends Page{// ...protected function booted(): void{parent::booted();// ...}}
Создание ссылки на страницу в ресурсе
В данном примере для создания ссылки на новую страницу будем использовать ActionButton и метод getPageUrl.
use MoonShine\Support\ListOf;use MoonShine\UI\Components\ActionButton;/*** @throws Throwable*/public function indexButtons(): ListOf{return parent::indexButtons()->add(ActionButton::make('To custom page',url: fn($model) => $this->getPageUrl(PostPage::class, params: ['resourceItem' => $model->getKey()]),),);}
use MoonShine\Support\ListOf;use MoonShine\UI\Components\ActionButton;/*** @throws Throwable*/public function indexButtons(): ListOf{return parent::indexButtons()->add(ActionButton::make('To custom page',url: fn($model) => $this->getPageUrl(PostPage::class, params: ['resourceItem' => $model->getKey()]),),);}
Assets
use MoonShine\AssetManager\Css;use MoonShine\AssetManager\Js;protected function onLoad(): void{parent::onLoad();$this->getAssetManager()->add(Css::make('/css/app.css'))->append(Js::make('/js/app.js'));}
use MoonShine\AssetManager\Css;use MoonShine\AssetManager\Js;protected function onLoad(): void{parent::onLoad();$this->getAssetManager()->add(Css::make('/css/app.css'))->append(Js::make('/js/app.js'));}