Installation:
composer require agencetwogether/hookshelper
Publish the config (optional, but recommended for customization):
php artisan vendor:publish --tag="hookshelper-config"
Register the Plugin:
Add the plugin to your Filament admin panel in app/Providers/Filament/AdminPanelProvider.php:
public function panel(Panel $panel): Panel
{
return $panel
->plugins([
\Agencetwogether\HooksHelper\HooksHelperPlugin::make(),
]);
}
First Use Case:
config/hookshelper.php) to adjust its position or visibility.Debugging Render Hooks:
RecordTable.BulkActions), toggle the helper to confirm the hook exists and its exact name.// In a Filament widget or page:
use Agencetwogether\HooksHelper\Facades\HooksHelper;
HooksHelper::addHook('RecordTable.BulkActions', view('filament.custom-bulk-actions'));
Dynamic Hook Injection:
Page.Header slot only on specific pages:
if (request()->routeIs('filament.pages.custom-page')) {
HooksHelper::addHook('Page.Header', view('filament.custom-header'));
}
Testing Hooks:
FeatureTest:
public function test_hook_is_registered()
{
$response = $this->get('/filament/resources/posts');
$response->assertSee('RecordTable.BulkActions'); // Check if hook exists via UI
}
Customizing the Toggle Button:
// config/hookshelper.php
'icon' => 'heroicon-o-cog', // Default: 'heroicon-o-code-bracket'
'placement' => 'top-right', // Options: 'top-left', 'bottom-left', 'bottom-right'
Minification Toggle:
'minify' => env('HOOKSHELPER_MINIFY', false),
Extending Hooks:
public function boot()
{
HooksHelper::addGlobalHook('GlobalFooter', view('filament.global-footer'));
}
Conditional Hooks:
app/Providers/HooksHelperServiceProvider.php):
if (app()->environment('local')) {
HooksHelper::enable();
}
Performance Overhead:
'enabled' => app()->environment('local'),
Hook Naming Conflicts:
custom.RecordTable.BulkActions) or verify uniqueness via the helper’s UI.Caching:
php artisan filament:cache).php artisan filament:cache-clear
Hook Scope:
getPages() or getWidgets() methods of Filament resources/pages.Inspecting Hooks:
data-hook-name attribute to confirm hook names.hookshelper.Logging Hooks:
config/hookshelper.php:
'debug' => true,
storage/logs/laravel.log for hook registration events.Disabling Specific Hooks:
'exclude_hooks' => [
'filament.admin.*', // Exclude all admin-related hooks
'custom.ignored-hook',
],
Testing Hooks in CI:
HooksHelper::shouldReceive('getHooks')->andReturn(['test.hook' => 'Test Hook']);
Custom Hook Providers:
namespace App\Providers;
use Agencetwogether\HooksHelper\Contracts\HookProvider;
use Illuminate\Support\Facades\Blade;
class CustomHookProvider implements HookProvider
{
public function register()
{
HooksHelper::addHook('Page.Header', function () {
Blade::render('filament.custom-header');
});
}
}
config/hookshelper.php:
'providers' => [
\App\Providers\CustomHookProvider::class,
],
Hook Events:
use Agencetwogether\HooksHelper\Events\HookRegistered;
HookRegistered::listen(function (HookRegistered $event) {
logger()->info("Hook registered: {$event->hookName}");
});
Localization:
php artisan vendor:publish --tag="hookshelper-lang"
resources/lang/vendor/hookshelper.php:
return [
'hooks' => [
'custom.hook' => 'Custom Hook (Translated)',
],
];
How can I help you explore Laravel packages today?