ModelResource
расширяет CrudResource
и предоставляет функциональность для работы с моделями Eloquent.
Он обеспечивает основу для создания ресурсов, связанных с моделями базы данных.
ModelResource
предоставляет методы для выполнения CRUD-операций, управления отношениями, применения фильтров и многое другое.
Вы также можете ознакомиться с разделом CrudResource.
CrudResource
- это абстрактный класс предоставляющий базовый интерфейс для CRUD
операций без привязки к хранилищу и типу данных.
Под капотом, ModelResource
расширяет CrudResource
и сразу включает возможность работы с Eloquent.
Если углубляться в детали MoonShine, то вы увидите все те же стандартные Controller, Model и Blade views.
Если бы вы разрабатывали самостоятельно, то создать ресурс контроллеры и ресурс маршруты можно следующим образом:
php artisan make:controller Controller --resource
php artisan make:controller Controller --resource
php artisan make:controller Controller --resource
php artisan make:controller Controller --resource
php artisan make:controller Controller --resource
use Illuminate\Support\Facades\Route;
Route::resource('resources', Controller::class);
namespaces
use Illuminate\Support\Facades\Route;
Route::resource('resources', Controller::class);
use Illuminate\Support\Facades\Route;
Route::resource('resources', Controller::class);
namespaces
use Illuminate\Support\Facades\Route;
Route::resource('resources', Controller::class);
use Illuminate\Support\Facades\Route;
Route::resource('resources', Controller::class);
Но эту работу можно поручить админ-панели MoonShine, которая будет их генерировать и объявлять самостоятельно.
ModelResource
является основным компонентом для создания раздела в админ-панели при работе с базой данных.
php artisan moonshine:resource Post
php artisan moonshine:resource Post
php artisan moonshine:resource Post
php artisan moonshine:resource Post
php artisan moonshine:resource Post
Для более подробной информации обратитесь к разделу Команды.
Базовые параметры, которые можно менять у ресурса, чтобы кастомизировать его работу.
namespace App\MoonShine\Resources;
use App\Models\Post;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
protected string $model = Post::class;
protected string $title = 'Posts';
protected array $with = ['category'];
protected string $column = 'id';
}
namespaces
namespace App\MoonShine\Resources;
use App\Models\Post;
use MoonShine\Laravel\Resources\ModelResource;
/**
* @extends ModelResource<Post>
*/
class PostResource extends ModelResource
{
// Модель
protected string $model = Post::class;
// Заголовок раздела
protected string $title = 'Posts';
// Eager load
protected array $with = ['category'];
// Поле для отображения значений в связях и хлебных крошках
protected string $column = 'id';
// ...
}
namespace App\MoonShine\Resources;
use App\Models\Post;
use MoonShine\Laravel\Resources\ModelResource;
/**
* @extends ModelResource<Post>
*/
class PostResource extends ModelResource
{
// Модель
protected string $model = Post::class;
// Заголовок раздела
protected string $title = 'Posts';
// Eager load
protected array $with = ['category'];
// Поле для отображения значений в связях и хлебных крошках
protected string $column = 'id';
// ...
}
namespaces
namespace App\MoonShine\Resources;
use App\Models\Post;
use MoonShine\Laravel\Resources\ModelResource;
/**
* @extends ModelResource<Post>
*/
class PostResource extends ModelResource
{
// Модель
protected string $model = Post::class;
// Заголовок раздела
protected string $title = 'Posts';
// Eager load
protected array $with = ['category'];
// Поле для отображения значений в связях и хлебных крошках
protected string $column = 'id';
// ...
}
namespace App\MoonShine\Resources;
use App\Models\Post;
use MoonShine\Laravel\Resources\ModelResource;
/**
* @extends ModelResource<Post>
*/
class PostResource extends ModelResource
{
// Модель
protected string $model = Post::class;
// Заголовок раздела
protected string $title = 'Posts';
// Eager load
protected array $with = ['category'];
// Поле для отображения значений в связях и хлебных крошках
protected string $column = 'id';
// ...
}

Ресурс автоматически регистрируется в MoonShineServiceProvider
при вызове команды php artisan moonshine:resource
.
Но если вы создаете раздел вручную, то вам необходимо самостоятельно его объявить в системе в MoonShineServiceProvider
.
namespace App\Providers;
use App\MoonShine\Resources\ArticleResource;
use Illuminate\Support\ServiceProvider;
use MoonShine\Contracts\Core\DependencyInjection\CoreContract;
use MoonShine\Laravel\DependencyInjection\ConfiguratorContract;
use MoonShine\Laravel\DependencyInjection\MoonShine;
use MoonShine\Laravel\DependencyInjection\MoonShineConfigurator;
class MoonShineServiceProvider extends ServiceProvider
{
public function boot(
CoreContract $core,
ConfiguratorContract $config,
): void
{
$core
->resources([
MoonShineUserResource::class,
MoonShineUserRoleResource::class,
ArticleResource::class,
])
->pages([
...$config->getPages(),
])
;
}
}
namespaces
namespace App\Providers;
use App\MoonShine\Resources\ArticleResource;
use Illuminate\Support\ServiceProvider;
use MoonShine\Contracts\Core\DependencyInjection\CoreContract;
use MoonShine\Laravel\DependencyInjection\ConfiguratorContract;
use MoonShine\Laravel\DependencyInjection\MoonShine;
use MoonShine\Laravel\DependencyInjection\MoonShineConfigurator;
class MoonShineServiceProvider extends ServiceProvider
{
/**
* @param MoonShine $core
* @param MoonShineConfigurator $config
*
*/
public function boot(
CoreContract $core,
ConfiguratorContract $config,
): void
{
$core
->resources([
MoonShineUserResource::class,
MoonShineUserRoleResource::class,
ArticleResource::class,
// ...
])
->pages([
...$config->getPages(),
])
;
}
}
namespace App\Providers;
use App\MoonShine\Resources\ArticleResource;
use Illuminate\Support\ServiceProvider;
use MoonShine\Contracts\Core\DependencyInjection\CoreContract;
use MoonShine\Laravel\DependencyInjection\ConfiguratorContract;
use MoonShine\Laravel\DependencyInjection\MoonShine;
use MoonShine\Laravel\DependencyInjection\MoonShineConfigurator;
class MoonShineServiceProvider extends ServiceProvider
{
/**
* @param MoonShine $core
* @param MoonShineConfigurator $config
*
*/
public function boot(
CoreContract $core,
ConfiguratorContract $config,
): void
{
$core
->resources([
MoonShineUserResource::class,
MoonShineUserRoleResource::class,
ArticleResource::class,
// ...
])
->pages([
...$config->getPages(),
])
;
}
}
namespaces
namespace App\Providers;
use App\MoonShine\Resources\ArticleResource;
use Illuminate\Support\ServiceProvider;
use MoonShine\Contracts\Core\DependencyInjection\CoreContract;
use MoonShine\Laravel\DependencyInjection\ConfiguratorContract;
use MoonShine\Laravel\DependencyInjection\MoonShine;
use MoonShine\Laravel\DependencyInjection\MoonShineConfigurator;
class MoonShineServiceProvider extends ServiceProvider
{
/**
* @param MoonShine $core
* @param MoonShineConfigurator $config
*
*/
public function boot(
CoreContract $core,
ConfiguratorContract $config,
): void
{
$core
->resources([
MoonShineUserResource::class,
MoonShineUserRoleResource::class,
ArticleResource::class,
// ...
])
->pages([
...$config->getPages(),
])
;
}
}
namespace App\Providers;
use App\MoonShine\Resources\ArticleResource;
use Illuminate\Support\ServiceProvider;
use MoonShine\Contracts\Core\DependencyInjection\CoreContract;
use MoonShine\Laravel\DependencyInjection\ConfiguratorContract;
use MoonShine\Laravel\DependencyInjection\MoonShine;
use MoonShine\Laravel\DependencyInjection\MoonShineConfigurator;
class MoonShineServiceProvider extends ServiceProvider
{
/**
* @param MoonShine $core
* @param MoonShineConfigurator $config
*
*/
public function boot(
CoreContract $core,
ConfiguratorContract $config,
): void
{
$core
->resources([
MoonShineUserResource::class,
MoonShineUserRoleResource::class,
ArticleResource::class,
// ...
])
->pages([
...$config->getPages(),
])
;
}
}
В MoonShine также доступна автозагрузка страниц и ресурсов.
Она выключена по-умолчанию и для активации нужно вызвать метод autoload()
в MoonShineServiceProvider
вместо указания ссылок на страницы и ресурсы.
namespace App\Providers;
use App\MoonShine\Resources\ArticleResource;
use Illuminate\Support\ServiceProvider;
use MoonShine\Contracts\Core\DependencyInjection\CoreContract;
use MoonShine\Laravel\DependencyInjection\ConfiguratorContract;
class MoonShineServiceProvider extends ServiceProvider
{
public function boot(
CoreContract $core,
ConfiguratorContract $config,
): void
{
$core->autoload();
}
}
namespaces
namespace App\Providers;
use App\MoonShine\Resources\ArticleResource;
use Illuminate\Support\ServiceProvider;
use MoonShine\Contracts\Core\DependencyInjection\CoreContract;
use MoonShine\Laravel\DependencyInjection\ConfiguratorContract;
class MoonShineServiceProvider extends ServiceProvider
{
public function boot(
CoreContract $core,
ConfiguratorContract $config,
): void
{
$core->autoload();
}
}
namespace App\Providers;
use App\MoonShine\Resources\ArticleResource;
use Illuminate\Support\ServiceProvider;
use MoonShine\Contracts\Core\DependencyInjection\CoreContract;
use MoonShine\Laravel\DependencyInjection\ConfiguratorContract;
class MoonShineServiceProvider extends ServiceProvider
{
public function boot(
CoreContract $core,
ConfiguratorContract $config,
): void
{
$core->autoload();
}
}
namespaces
namespace App\Providers;
use App\MoonShine\Resources\ArticleResource;
use Illuminate\Support\ServiceProvider;
use MoonShine\Contracts\Core\DependencyInjection\CoreContract;
use MoonShine\Laravel\DependencyInjection\ConfiguratorContract;
class MoonShineServiceProvider extends ServiceProvider
{
public function boot(
CoreContract $core,
ConfiguratorContract $config,
): void
{
$core->autoload();
}
}
namespace App\Providers;
use App\MoonShine\Resources\ArticleResource;
use Illuminate\Support\ServiceProvider;
use MoonShine\Contracts\Core\DependencyInjection\CoreContract;
use MoonShine\Laravel\DependencyInjection\ConfiguratorContract;
class MoonShineServiceProvider extends ServiceProvider
{
public function boot(
CoreContract $core,
ConfiguratorContract $config,
): void
{
$core->autoload();
}
}
При деплое проекта на продакшен в Laravel 11+ рекомендуется вызывать консольную команду php artisan optimize
.
Помимо её основных функций, она также выполнит кэширование ресурсов MoonShine.
При использовании Laravel 10 необходимо вручную вызывать консольную команду php artisan moonshine:optimize
для оптимизации процесса инициализации админ панели.
Очистить кэш панели можно как командой php artisan optimize:clear
в Laravel 11, так и прямым вызовом консольной команды php artisan moonshine:optimize-clear
.
Если после создания классов приложение их не видит - обновите кэш композера командой composer dump-autoload
.
Все страницы в MoonShine имеют Layout
и у каждой страницы он может быть свой.
По умолчанию при установке MoonShine добавляет базовый MoonShineLayout
в директорию app/MoonShine/Layouts
.
В Layout
кастомизируется всё, что отвечает за внешний вид ваших страниц и это касается также и навигации.
Чтобы добавить раздел в меню, необходимо объявить его через метод menu()
в Layout
.
namespace App\MoonShine\Layouts;
use App\MoonShine\Resources\PostResource;
use MoonShine\Laravel\Layouts\CompactLayout;
use MoonShine\Laravel\Resources\MoonShineUserResource;
use MoonShine\Laravel\Resources\MoonShineUserRoleResource;
use MoonShine\MenuManager\MenuGroup;
use MoonShine\MenuManager\MenuItem;
final class MoonShineLayout extends CompactLayout
{
protected function menu(): array
{
return [
MenuGroup::make(__('moonshine::ui.resource.system'), [
MenuItem::make(
__('moonshine::ui.resource.admins_title'),
MoonShineUserResource::class
),
MenuItem::make(
__('moonshine::ui.resource.role_title'),
MoonShineUserRoleResource::class
),
]),
MenuItem::make('Posts', PostResource::class),
];
}
}
namespaces
namespace App\MoonShine\Layouts;
use App\MoonShine\Resources\PostResource;
use MoonShine\Laravel\Layouts\CompactLayout;
use MoonShine\Laravel\Resources\MoonShineUserResource;
use MoonShine\Laravel\Resources\MoonShineUserRoleResource;
use MoonShine\MenuManager\MenuGroup;
use MoonShine\MenuManager\MenuItem;
final class MoonShineLayout extends CompactLayout
{
// ...
protected function menu(): array
{
return [
MenuGroup::make(__('moonshine::ui.resource.system'), [
MenuItem::make(
__('moonshine::ui.resource.admins_title'),
MoonShineUserResource::class
),
MenuItem::make(
__('moonshine::ui.resource.role_title'),
MoonShineUserRoleResource::class
),
]),
MenuItem::make('Posts', PostResource::class),
// ...
];
}
}
namespace App\MoonShine\Layouts;
use App\MoonShine\Resources\PostResource;
use MoonShine\Laravel\Layouts\CompactLayout;
use MoonShine\Laravel\Resources\MoonShineUserResource;
use MoonShine\Laravel\Resources\MoonShineUserRoleResource;
use MoonShine\MenuManager\MenuGroup;
use MoonShine\MenuManager\MenuItem;
final class MoonShineLayout extends CompactLayout
{
// ...
protected function menu(): array
{
return [
MenuGroup::make(__('moonshine::ui.resource.system'), [
MenuItem::make(
__('moonshine::ui.resource.admins_title'),
MoonShineUserResource::class
),
MenuItem::make(
__('moonshine::ui.resource.role_title'),
MoonShineUserRoleResource::class
),
]),
MenuItem::make('Posts', PostResource::class),
// ...
];
}
}
namespaces
namespace App\MoonShine\Layouts;
use App\MoonShine\Resources\PostResource;
use MoonShine\Laravel\Layouts\CompactLayout;
use MoonShine\Laravel\Resources\MoonShineUserResource;
use MoonShine\Laravel\Resources\MoonShineUserRoleResource;
use MoonShine\MenuManager\MenuGroup;
use MoonShine\MenuManager\MenuItem;
final class MoonShineLayout extends CompactLayout
{
// ...
protected function menu(): array
{
return [
MenuGroup::make(__('moonshine::ui.resource.system'), [
MenuItem::make(
__('moonshine::ui.resource.admins_title'),
MoonShineUserResource::class
),
MenuItem::make(
__('moonshine::ui.resource.role_title'),
MoonShineUserRoleResource::class
),
]),
MenuItem::make('Posts', PostResource::class),
// ...
];
}
}
namespace App\MoonShine\Layouts;
use App\MoonShine\Resources\PostResource;
use MoonShine\Laravel\Layouts\CompactLayout;
use MoonShine\Laravel\Resources\MoonShineUserResource;
use MoonShine\Laravel\Resources\MoonShineUserRoleResource;
use MoonShine\MenuManager\MenuGroup;
use MoonShine\MenuManager\MenuItem;
final class MoonShineLayout extends CompactLayout
{
// ...
protected function menu(): array
{
return [
MenuGroup::make(__('moonshine::ui.resource.system'), [
MenuItem::make(
__('moonshine::ui.resource.admins_title'),
MoonShineUserResource::class
),
MenuItem::make(
__('moonshine::ui.resource.role_title'),
MoonShineUserRoleResource::class
),
]),
MenuItem::make('Posts', PostResource::class),
// ...
];
}
}
О расширенных настройках Layout
можно узнать в разделе Layout.
О расширенных настройках MenuManager
можно узнать в разделе Menu.
По умолчанию alias ресурса, который используется в url
, генерируется на основе наименования класс в kebab-case
, например:
MoonShineUserResource
-> moon-shine-user-resource
.
Для того чтобы изменить alias
, можно воспользоваться свойством ресурса $alias
или методом getAlias()
.
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
protected ?string $alias = 'custom-alias';
}
namespaces
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
protected ?string $alias = 'custom-alias';
// ...
}
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
protected ?string $alias = 'custom-alias';
// ...
}
namespaces
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
protected ?string $alias = 'custom-alias';
// ...
}
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
protected ?string $alias = 'custom-alias';
// ...
}
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
public function getAlias(): ?string
{
return 'custom-alias';
}
}
namespaces
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
public function getAlias(): ?string
{
return 'custom-alias';
}
}
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
public function getAlias(): ?string
{
return 'custom-alias';
}
}
namespaces
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
public function getAlias(): ?string
{
return 'custom-alias';
}
}
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
public function getAlias(): ?string
{
return 'custom-alias';
}
}
Если в url
детальной страницы или страницы редактирования присутствует параметр resourceItem
, то в ресурсе вы можете получить доступ к текущему элементу через метод getItem()
.
$this->getItem();
$this->getItem();
$this->getItem();
$this->getItem();
$this->getItem();
Через метод getModel()
можно получить доступ к модели.
$this->getModel();
$this->getModel();
$this->getModel();
$this->getModel();
$this->getModel();
Вы можете добавлять, редактировать и просматривать записи прямо на странице со списком в модальном окне.
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
protected bool $createInModal = true;
protected bool $editInModal = true;
protected bool $detailInModal = true;
}
namespaces
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
protected bool $createInModal = true;
protected bool $editInModal = true;
protected bool $detailInModal = true;
// ...
}
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
protected bool $createInModal = true;
protected bool $editInModal = true;
protected bool $detailInModal = true;
// ...
}
namespaces
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
protected bool $createInModal = true;
protected bool $editInModal = true;
protected bool $detailInModal = true;
// ...
}
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
protected bool $createInModal = true;
protected bool $editInModal = true;
protected bool $detailInModal = true;
// ...
}
По умолчанию при создании и редактировании записи осуществляется редирект на страницу с формой, но это поведение можно контролировать.
Через свойство в ресурсе:
use MoonShine\Support\Enums\PageType;
protected ?PageType $redirectAfterSave = PageType::FORM;
namespaces
use MoonShine\Support\Enums\PageType;
protected ?PageType $redirectAfterSave = PageType::FORM;
use MoonShine\Support\Enums\PageType;
protected ?PageType $redirectAfterSave = PageType::FORM;
namespaces
use MoonShine\Support\Enums\PageType;
protected ?PageType $redirectAfterSave = PageType::FORM;
use MoonShine\Support\Enums\PageType;
protected ?PageType $redirectAfterSave = PageType::FORM;
Через метод:
public function getRedirectAfterSave(): string
{
return '/';
}
public function getRedirectAfterSave(): string
{
return '/';
}
public function getRedirectAfterSave(): string
{
return '/';
}
public function getRedirectAfterSave(): string
{
return '/';
}
public function getRedirectAfterSave(): string
{
return '/';
}
Также доступен редирект после удаления:
public function getRedirectAfterDelete(): string
{
return $this->getIndexPageUrl();
}
public function getRedirectAfterDelete(): string
{
return $this->getIndexPageUrl();
}
public function getRedirectAfterDelete(): string
{
return $this->getIndexPageUrl();
}
public function getRedirectAfterDelete(): string
{
return $this->getIndexPageUrl();
}
public function getRedirectAfterDelete(): string
{
return $this->getIndexPageUrl();
}
Часто бывает, что необходимо создать ресурс, в котором будет исключена возможность удалять, или добавлять, или редактировать.
И здесь речь не об авторизации, а о глобальном исключении этих разделов.
Делается это крайне просто за счет метода activeActions()
в ресурсе.
namespace App\MoonShine\Resources;
use MoonShine\Support\ListOf;
use MoonShine\Laravel\Enums\Action;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
protected function activeActions(): ListOf
{
return parent::activeActions()
->except(Action::VIEW, Action::MASS_DELETE)
;
}
}
namespaces
namespace App\MoonShine\Resources;
use MoonShine\Support\ListOf;
use MoonShine\Laravel\Enums\Action;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
// ...
protected function activeActions(): ListOf
{
return parent::activeActions()
->except(Action::VIEW, Action::MASS_DELETE)
// ->only(Action::VIEW)
;
}
}
namespace App\MoonShine\Resources;
use MoonShine\Support\ListOf;
use MoonShine\Laravel\Enums\Action;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
// ...
protected function activeActions(): ListOf
{
return parent::activeActions()
->except(Action::VIEW, Action::MASS_DELETE)
// ->only(Action::VIEW)
;
}
}
namespaces
namespace App\MoonShine\Resources;
use MoonShine\Support\ListOf;
use MoonShine\Laravel\Enums\Action;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
// ...
protected function activeActions(): ListOf
{
return parent::activeActions()
->except(Action::VIEW, Action::MASS_DELETE)
// ->only(Action::VIEW)
;
}
}
namespace App\MoonShine\Resources;
use MoonShine\Support\ListOf;
use MoonShine\Laravel\Enums\Action;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
// ...
protected function activeActions(): ListOf
{
return parent::activeActions()
->except(Action::VIEW, Action::MASS_DELETE)
// ->only(Action::VIEW)
;
}
}
Также можно просто создать новый список, например:
use MoonShine\Laravel\Enums\Action;
use MoonShine\Support\ListOf;
protected function activeActions(): ListOf
{
return new ListOf(Action::class, [Action::VIEW, Action::UPDATE]);
}
namespaces
use MoonShine\Laravel\Enums\Action;
use MoonShine\Support\ListOf;
protected function activeActions(): ListOf
{
return new ListOf(Action::class, [Action::VIEW, Action::UPDATE]);
}
use MoonShine\Laravel\Enums\Action;
use MoonShine\Support\ListOf;
protected function activeActions(): ListOf
{
return new ListOf(Action::class, [Action::VIEW, Action::UPDATE]);
}
namespaces
use MoonShine\Laravel\Enums\Action;
use MoonShine\Support\ListOf;
protected function activeActions(): ListOf
{
return new ListOf(Action::class, [Action::VIEW, Action::UPDATE]);
}
use MoonShine\Laravel\Enums\Action;
use MoonShine\Support\ListOf;
protected function activeActions(): ListOf
{
return new ListOf(Action::class, [Action::VIEW, Action::UPDATE]);
}
По умолчанию на индексной странице ресурса модели присутствует только кнопка для создания.
Метод topButtons()
позволяет добавить дополнительные кнопки.
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
use MoonShine\Support\AlpineJs;
use MoonShine\Support\Enums\JsEvent;
use MoonShine\Support\ListOf;
use MoonShine\UI\Components\ActionButton;
class PostResource extends ModelResource
{
protected function topButtons(): ListOf
{
return parent::topButtons()->add(
ActionButton::make('Refresh', '#')
->dispatchEvent(AlpineJs::event(JsEvent::TABLE_UPDATED, $this->getListComponentName()))
);
}
}
namespaces
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
use MoonShine\Support\AlpineJs;
use MoonShine\Support\Enums\JsEvent;
use MoonShine\Support\ListOf;
use MoonShine\UI\Components\ActionButton;
class PostResource extends ModelResource
{
// ...
protected function topButtons(): ListOf
{
return parent::topButtons()->add(
ActionButton::make('Refresh', '#')
->dispatchEvent(AlpineJs::event(JsEvent::TABLE_UPDATED, $this->getListComponentName()))
);
}
}
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
use MoonShine\Support\AlpineJs;
use MoonShine\Support\Enums\JsEvent;
use MoonShine\Support\ListOf;
use MoonShine\UI\Components\ActionButton;
class PostResource extends ModelResource
{
// ...
protected function topButtons(): ListOf
{
return parent::topButtons()->add(
ActionButton::make('Refresh', '#')
->dispatchEvent(AlpineJs::event(JsEvent::TABLE_UPDATED, $this->getListComponentName()))
);
}
}
namespaces
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
use MoonShine\Support\AlpineJs;
use MoonShine\Support\Enums\JsEvent;
use MoonShine\Support\ListOf;
use MoonShine\UI\Components\ActionButton;
class PostResource extends ModelResource
{
// ...
protected function topButtons(): ListOf
{
return parent::topButtons()->add(
ActionButton::make('Refresh', '#')
->dispatchEvent(AlpineJs::event(JsEvent::TABLE_UPDATED, $this->getListComponentName()))
);
}
}
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
use MoonShine\Support\AlpineJs;
use MoonShine\Support\Enums\JsEvent;
use MoonShine\Support\ListOf;
use MoonShine\UI\Components\ActionButton;
class PostResource extends ModelResource
{
// ...
protected function topButtons(): ListOf
{
return parent::topButtons()->add(
ActionButton::make('Refresh', '#')
->dispatchEvent(AlpineJs::event(JsEvent::TABLE_UPDATED, $this->getListComponentName()))
);
}
}
Вы также можете изменить отображение кнопок, отображать их в линию или же в выпадающем меню для экономии места.
namespace App\MoonShine\Resources;
use MoonShine\Support\ListOf;
use MoonShine\UI\Components\ActionButton;
class PostResource extends ModelResource
{
protected function indexButtons(): ListOf
{
return parent::indexButtons()->prepend(
ActionButton::make('Button 1', '/')
->showInLine(),
ActionButton::make('Button 2', '/')
->showInDropdown(),
);
}
}
namespaces
namespace App\MoonShine\Resources;
use MoonShine\Support\ListOf;
use MoonShine\UI\Components\ActionButton;
class PostResource extends ModelResource
{
// ...
protected function indexButtons(): ListOf
{
return parent::indexButtons()->prepend(
ActionButton::make('Button 1', '/')
->showInLine(),
ActionButton::make('Button 2', '/')
->showInDropdown(),
);
}
}
namespace App\MoonShine\Resources;
use MoonShine\Support\ListOf;
use MoonShine\UI\Components\ActionButton;
class PostResource extends ModelResource
{
// ...
protected function indexButtons(): ListOf
{
return parent::indexButtons()->prepend(
ActionButton::make('Button 1', '/')
->showInLine(),
ActionButton::make('Button 2', '/')
->showInDropdown(),
);
}
}
namespaces
namespace App\MoonShine\Resources;
use MoonShine\Support\ListOf;
use MoonShine\UI\Components\ActionButton;
class PostResource extends ModelResource
{
// ...
protected function indexButtons(): ListOf
{
return parent::indexButtons()->prepend(
ActionButton::make('Button 1', '/')
->showInLine(),
ActionButton::make('Button 2', '/')
->showInDropdown(),
);
}
}
namespace App\MoonShine\Resources;
use MoonShine\Support\ListOf;
use MoonShine\UI\Components\ActionButton;
class PostResource extends ModelResource
{
// ...
protected function indexButtons(): ListOf
{
return parent::indexButtons()->prepend(
ActionButton::make('Button 1', '/')
->showInLine(),
ActionButton::make('Button 2', '/')
->showInDropdown(),
);
}
}
Для модификации основного компонента IndexPage
, FormPage
или DetailPage
страницы из ресурса можно переопределить соответствующие методы modifyListComponent()
, modifyFormComponent()
и modifyDetailComponent()
.
use MoonShine\Contracts\UI\ComponentContract;
public function modifyListComponent(ComponentContract $component): ComponentContract
{
return parent::modifyListComponent($component)->customAttributes([
'data-my-attr' => 'value'
]);
}
namespaces
use MoonShine\Contracts\UI\ComponentContract;
public function modifyListComponent(ComponentContract $component): ComponentContract
{
return parent::modifyListComponent($component)->customAttributes([
'data-my-attr' => 'value'
]);
}
use MoonShine\Contracts\UI\ComponentContract;
public function modifyListComponent(ComponentContract $component): ComponentContract
{
return parent::modifyListComponent($component)->customAttributes([
'data-my-attr' => 'value'
]);
}
namespaces
use MoonShine\Contracts\UI\ComponentContract;
public function modifyListComponent(ComponentContract $component): ComponentContract
{
return parent::modifyListComponent($component)->customAttributes([
'data-my-attr' => 'value'
]);
}
use MoonShine\Contracts\UI\ComponentContract;
public function modifyListComponent(ComponentContract $component): ComponentContract
{
return parent::modifyListComponent($component)->customAttributes([
'data-my-attr' => 'value'
]);
}
use MoonShine\Contracts\UI\ComponentContract;
use MoonShine\UI\Components\FlexibleRender;
public function modifyFormComponent(ComponentContract $component): ComponentContract
{
return parent::modifyFormComponent($component)->fields([
FlexibleRender::make('Top'),
...parent::modifyFormComponent($component)->getFields()->toArray(),
FlexibleRender::make('Bottom'),
])->submit('Go');
}
namespaces
use MoonShine\Contracts\UI\ComponentContract;
use MoonShine\UI\Components\FlexibleRender;
public function modifyFormComponent(ComponentContract $component): ComponentContract
{
return parent::modifyFormComponent($component)->fields([
FlexibleRender::make('Top'),
...parent::modifyFormComponent($component)->getFields()->toArray(),
FlexibleRender::make('Bottom'),
])->submit('Go');
}
use MoonShine\Contracts\UI\ComponentContract;
use MoonShine\UI\Components\FlexibleRender;
public function modifyFormComponent(ComponentContract $component): ComponentContract
{
return parent::modifyFormComponent($component)->fields([
FlexibleRender::make('Top'),
...parent::modifyFormComponent($component)->getFields()->toArray(),
FlexibleRender::make('Bottom'),
])->submit('Go');
}
namespaces
use MoonShine\Contracts\UI\ComponentContract;
use MoonShine\UI\Components\FlexibleRender;
public function modifyFormComponent(ComponentContract $component): ComponentContract
{
return parent::modifyFormComponent($component)->fields([
FlexibleRender::make('Top'),
...parent::modifyFormComponent($component)->getFields()->toArray(),
FlexibleRender::make('Bottom'),
])->submit('Go');
}
use MoonShine\Contracts\UI\ComponentContract;
use MoonShine\UI\Components\FlexibleRender;
public function modifyFormComponent(ComponentContract $component): ComponentContract
{
return parent::modifyFormComponent($component)->fields([
FlexibleRender::make('Top'),
...parent::modifyFormComponent($component)->getFields()->toArray(),
FlexibleRender::make('Bottom'),
])->submit('Go');
}
use MoonShine\Contracts\UI\ComponentContract;
public function modifyDetailComponent(ComponentContract $component): ComponentContract
{
return parent::modifyDetailComponent($component)->customAttributes([
'data-my-attr' => 'value'
]);
}
namespaces
use MoonShine\Contracts\UI\ComponentContract;
public function modifyDetailComponent(ComponentContract $component): ComponentContract
{
return parent::modifyDetailComponent($component)->customAttributes([
'data-my-attr' => 'value'
]);
}
use MoonShine\Contracts\UI\ComponentContract;
public function modifyDetailComponent(ComponentContract $component): ComponentContract
{
return parent::modifyDetailComponent($component)->customAttributes([
'data-my-attr' => 'value'
]);
}
namespaces
use MoonShine\Contracts\UI\ComponentContract;
public function modifyDetailComponent(ComponentContract $component): ComponentContract
{
return parent::modifyDetailComponent($component)->customAttributes([
'data-my-attr' => 'value'
]);
}
use MoonShine\Contracts\UI\ComponentContract;
public function modifyDetailComponent(ComponentContract $component): ComponentContract
{
return parent::modifyDetailComponent($component)->customAttributes([
'data-my-attr' => 'value'
]);
}
Лучший способ изменить компоненты страниц - это опубликовать страницы и взаимодействовать через них.
Но, если вы хотите быстро добавить компоненты на страницы, то можете воспользоваться методами ресурса pageComponents()
, indexPageComponents()
, formPageComponents()
и detailPageComponents()
.
use MoonShine\Core\Collections\Components;
use MoonShine\UI\Components\FormBuilder;
use MoonShine\UI\Components\Modal;
use MoonShine\UI\Fields\Text;
protected function pageComponents(): array
{
return [
Modal::make(
'My Modal'
components: Components::make([
FormBuilder::make()->fields([
Text::make('Title')
])
])
)
->name('demo-modal')
];
}
namespaces
use MoonShine\Core\Collections\Components;
use MoonShine\UI\Components\FormBuilder;
use MoonShine\UI\Components\Modal;
use MoonShine\UI\Fields\Text;
// or indexPageComponents/formPageComponents/detailPageComponents
protected function pageComponents(): array
{
return [
Modal::make(
'My Modal'
components: Components::make([
FormBuilder::make()->fields([
Text::make('Title')
])
])
)
->name('demo-modal')
];
}
use MoonShine\Core\Collections\Components;
use MoonShine\UI\Components\FormBuilder;
use MoonShine\UI\Components\Modal;
use MoonShine\UI\Fields\Text;
// or indexPageComponents/formPageComponents/detailPageComponents
protected function pageComponents(): array
{
return [
Modal::make(
'My Modal'
components: Components::make([
FormBuilder::make()->fields([
Text::make('Title')
])
])
)
->name('demo-modal')
];
}
namespaces
use MoonShine\Core\Collections\Components;
use MoonShine\UI\Components\FormBuilder;
use MoonShine\UI\Components\Modal;
use MoonShine\UI\Fields\Text;
// or indexPageComponents/formPageComponents/detailPageComponents
protected function pageComponents(): array
{
return [
Modal::make(
'My Modal'
components: Components::make([
FormBuilder::make()->fields([
Text::make('Title')
])
])
)
->name('demo-modal')
];
}
use MoonShine\Core\Collections\Components;
use MoonShine\UI\Components\FormBuilder;
use MoonShine\UI\Components\Modal;
use MoonShine\UI\Fields\Text;
// or indexPageComponents/formPageComponents/detailPageComponents
protected function pageComponents(): array
{
return [
Modal::make(
'My Modal'
components: Components::make([
FormBuilder::make()->fields([
Text::make('Title')
])
])
)
->name('demo-modal')
];
}
Компоненты будут добавлены в bottomLayer
.
Resource
имеет несколько различных методов подключения к различным частям своего жизненного цикла. Давайте пройдемся по ним:
Метод onLoad()
дает возможность интегрироваться в момент когда ресурс загружен и в данный момент является активным.
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
protected function onLoad(): void
{
}
}
namespaces
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
// ...
protected function onLoad(): void
{
// ...
}
}
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
// ...
protected function onLoad(): void
{
// ...
}
}
namespaces
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
// ...
protected function onLoad(): void
{
// ...
}
}
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
// ...
protected function onLoad(): void
{
// ...
}
}
Вы также можете подключить trait
к ресурсу и внутри trait
добавить метод согласно конвенции наименований - load{TraitName}
и через трейт обратиться к onLoad
ресурса.
namespace App\MoonShine\Resources;
use App\Traits\WithPermissions;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
use WithPermissions;
}
namespaces
namespace App\MoonShine\Resources;
use App\Traits\WithPermissions;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
use WithPermissions;
// ...
}
namespace App\MoonShine\Resources;
use App\Traits\WithPermissions;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
use WithPermissions;
// ...
}
namespaces
namespace App\MoonShine\Resources;
use App\Traits\WithPermissions;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
use WithPermissions;
// ...
}
namespace App\MoonShine\Resources;
use App\Traits\WithPermissions;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
use WithPermissions;
// ...
}
use MoonShine\Support\Enums\Layer;
use MoonShine\Support\Enums\PageType;
trait WithPermissions
{
protected function loadWithPermissions(): void
{
$this->getPages()
->findByUri(PageType::FORM->value)
->pushToLayer(
layer: Layer::BOTTOM,
component: Permissions::make(
label: 'Permissions',
resource: $this,
)
);
}
}
namespaces
use MoonShine\Support\Enums\Layer;
use MoonShine\Support\Enums\PageType;
trait WithPermissions
{
protected function loadWithPermissions(): void
{
$this->getPages()
->findByUri(PageType::FORM->value)
->pushToLayer(
layer: Layer::BOTTOM,
component: Permissions::make(
label: 'Permissions',
resource: $this,
)
);
}
}
use MoonShine\Support\Enums\Layer;
use MoonShine\Support\Enums\PageType;
trait WithPermissions
{
protected function loadWithPermissions(): void
{
$this->getPages()
->findByUri(PageType::FORM->value)
->pushToLayer(
layer: Layer::BOTTOM,
component: Permissions::make(
label: 'Permissions',
resource: $this,
)
);
}
}
namespaces
use MoonShine\Support\Enums\Layer;
use MoonShine\Support\Enums\PageType;
trait WithPermissions
{
protected function loadWithPermissions(): void
{
$this->getPages()
->findByUri(PageType::FORM->value)
->pushToLayer(
layer: Layer::BOTTOM,
component: Permissions::make(
label: 'Permissions',
resource: $this,
)
);
}
}
use MoonShine\Support\Enums\Layer;
use MoonShine\Support\Enums\PageType;
trait WithPermissions
{
protected function loadWithPermissions(): void
{
$this->getPages()
->findByUri(PageType::FORM->value)
->pushToLayer(
layer: Layer::BOTTOM,
component: Permissions::make(
label: 'Permissions',
resource: $this,
)
);
}
}
Метод onBoot()
дает возможность интегрироваться в момент когда MoonShine создает экземпляр ресурса в системе.
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
protected function onBoot(): void
{
}
}
namespaces
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
// ...
protected function onBoot(): void
{
// ...
}
}
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
// ...
protected function onBoot(): void
{
// ...
}
}
namespaces
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
// ...
protected function onBoot(): void
{
// ...
}
}
namespace App\MoonShine\Resources;
use MoonShine\Laravel\Resources\ModelResource;
class PostResource extends ModelResource
{
// ...
protected function onBoot(): void
{
// ...
}
}
Вы также можете подключить trait
к ресурсу и внутри trait
добавить метод согласно конвенции наименований - boot{TraitName}
и через трейт обратиться к onBoot()
ресурса.
use MoonShine\AssetManager\Css;
use MoonShine\AssetManager\Js;
protected function onLoad(): void
{
$this->getAssetManager()
->add(Css::make('/css/app.css'))
->append(Js::make('/js/app.js'));
}
namespaces
use MoonShine\AssetManager\Css;
use MoonShine\AssetManager\Js;
protected function onLoad(): void
{
$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
{
$this->getAssetManager()
->add(Css::make('/css/app.css'))
->append(Js::make('/js/app.js'));
}
namespaces
use MoonShine\AssetManager\Css;
use MoonShine\AssetManager\Js;
protected function onLoad(): void
{
$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
{
$this->getAssetManager()
->add(Css::make('/css/app.css'))
->append(Js::make('/js/app.js'));
}
Если ресурс в режиме "async", то вы можете модифицировать ответ:
use Symfony\Component\HttpFoundation\Response;
use MoonShine\Laravel\Http\Responses\MoonShineJsonResponse;
public function modifyDestroyResponse(MoonShineJsonResponse $response): MoonShineJsonResponse
{
return $response;
}
public function modifyMassDeleteResponse(MoonShineJsonResponse $response): MoonShineJsonResponse
{
return $response;
}
public function modifySaveResponse(MoonShineJsonResponse $response): MoonShineJsonResponse
{
return $response;
}
public function modifyErrorResponse(Response $response, Throwable $exception): Response
{
return $response;
}
use Symfony\Component\HttpFoundation\Response;
use MoonShine\Laravel\Http\Responses\MoonShineJsonResponse;
public function modifyDestroyResponse(MoonShineJsonResponse $response): MoonShineJsonResponse
{
return $response;
}
public function modifyMassDeleteResponse(MoonShineJsonResponse $response): MoonShineJsonResponse
{
return $response;
}
public function modifySaveResponse(MoonShineJsonResponse $response): MoonShineJsonResponse
{
return $response;
}
public function modifyErrorResponse(Response $response, Throwable $exception): Response
{
return $response;
}
use Symfony\Component\HttpFoundation\Response;
use MoonShine\Laravel\Http\Responses\MoonShineJsonResponse;
public function modifyDestroyResponse(MoonShineJsonResponse $response): MoonShineJsonResponse
{
return $response;
}
public function modifyMassDeleteResponse(MoonShineJsonResponse $response): MoonShineJsonResponse
{
return $response;
}
public function modifySaveResponse(MoonShineJsonResponse $response): MoonShineJsonResponse
{
return $response;
}
public function modifyErrorResponse(Response $response, Throwable $exception): Response
{
return $response;
}
use Symfony\Component\HttpFoundation\Response;
use MoonShine\Laravel\Http\Responses\MoonShineJsonResponse;
public function modifyDestroyResponse(MoonShineJsonResponse $response): MoonShineJsonResponse
{
return $response;
}
public function modifyMassDeleteResponse(MoonShineJsonResponse $response): MoonShineJsonResponse
{
return $response;
}
public function modifySaveResponse(MoonShineJsonResponse $response): MoonShineJsonResponse
{
return $response;
}
public function modifyErrorResponse(Response $response, Throwable $exception): Response
{
return $response;
}
use Symfony\Component\HttpFoundation\Response;
use MoonShine\Laravel\Http\Responses\MoonShineJsonResponse;
public function modifyDestroyResponse(MoonShineJsonResponse $response): MoonShineJsonResponse
{
return $response;
}
public function modifyMassDeleteResponse(MoonShineJsonResponse $response): MoonShineJsonResponse
{
return $response;
}
public function modifySaveResponse(MoonShineJsonResponse $response): MoonShineJsonResponse
{
return $response;
}
public function modifyErrorResponse(Response $response, Throwable $exception): Response
{
return $response;
}