Advanced

Handlers

Basics

Handlers in MoonShine are reusable handlers that allow you to easily add custom actions to resources.

The main advantages:

  • Do not require the creation of controllers,
  • Automatic error handling within MoonShine,
  • Many ready-made methods for interaction with the system,
  • Simple integration with UI through automatic button generation,
  • Automatically displayed in the interface after connection.

Creating Handler

To create a new Handler, use the command:

php artisan moonshine:handler MyCustomHandler
php artisan moonshine:handler MyCustomHandler

You can learn about all supported options in the section Commands.

After executing the command, a Handler class will be created in the app\MoonShine\Handlers directory with the following structure:

namespace App\MoonShine\Handlers; use MoonShine\UI\Exceptions\ActionButtonException; use MoonShine\Laravel\MoonShineUI; use MoonShine\Laravel\Handlers\Handler; use MoonShine\Contracts\UI\ActionButtonContract; use MoonShine\UI\Components\ActionButton; use Symfony\Component\HttpFoundation\Response; class MyCustomHandler extends Handler { /** * @throws ActionButtonException */ public function handle(): Response { if (! $this->hasResource()) { throw new ActionButtonException('Resource is required for action'); } if ($this->isQueue()) { // Job here MoonShineUI::toast( __('moonshine::ui.resource.queued') ); return back(); } self::process(); return back(); } public static function process() { // Logic here } public function getButton(): ActionButtonContract { return ActionButton::make($this->getLabel(), $this->getUrl()); } }
namespace App\MoonShine\Handlers;
 
use MoonShine\UI\Exceptions\ActionButtonException;
use MoonShine\Laravel\MoonShineUI;
use MoonShine\Laravel\Handlers\Handler;
use MoonShine\Contracts\UI\ActionButtonContract;
use MoonShine\UI\Components\ActionButton;
use Symfony\Component\HttpFoundation\Response;
 
class MyCustomHandler extends Handler
{
/**
* @throws ActionButtonException
*/
public function handle(): Response
{
if (! $this->hasResource()) {
throw new ActionButtonException('Resource is required for action');
}
 
if ($this->isQueue()) {
// Job here
 
MoonShineUI::toast(
__('moonshine::ui.resource.queued')
);
 
return back();
}
 
self::process();
 
return back();
}
 
public static function process()
{
// Logic here
}
 
public function getButton(): ActionButtonContract
{
return ActionButton::make($this->getLabel(), $this->getUrl());
}
}

Registration

To register a Handler in a resource, you need to override the handlers() method:

class PostResource extends ModelResource { protected function handlers(): ListOf { return parent::handlers()->add(new MyCustomHandler()); } }
class PostResource extends ModelResource
{
protected function handlers(): ListOf
{
return parent::handlers()->add(new MyCustomHandler());
}
}

After registration, a button for launching the Handler will automatically appear on the right side of the resource's index page.

Interaction

Handler is closely integrated with the resource and has access to:

  • The current resource via $this->getResource(),
  • Queueing capabilities,
  • Notification system and settings for users who will receive notifications via notifyUsers(),
  • Modifying the button via modifyButton().