# Filament Plugin Essentials - Complete LLM Documentation **Package Name**: `bezhansalleh/filament-plugin-essentials` **Version**: 1.0.0-beta **Purpose**: A collection of essential traits that streamline Filament plugin development by taking care of the boilerplate, so you can focus on shipping real features faster. ## Core Concept & Architecture This package implements a **3-tier default system** for Filament plugin configuration: 1. **User Overrides** (Highest Priority) - Configuration set by plugin users via fluent API 2. **Plugin Developer Defaults** (Middle Priority) - Defaults set by plugin developers 3. **Filament Core Defaults** (Lowest Priority) - Filament's built-in defaults The package provides **trait pairs**: Plugin traits that provide configuration methods, and Resource traits that delegate method calls to the plugin for consistent behavior. ### Key Innovation: Delegation Pattern Resources use traits that delegate method calls to their associated plugin, creating a seamless configuration flow: ``` Resource Method Call → Plugin Trait → User Override OR Plugin Default OR Filament Default ``` ## Package Structure ``` src/ ├── PluginEssentials.php # Empty final class (placeholder) ├── PluginEssentialsServiceProvider.php # Laravel service provider └── Concerns/ ├── Plugin/ # Traits for Plugin classes │ ├── HasNavigation.php # Navigation management (labels, icons, groups, sorting, badges) │ ├── HasLabels.php # Model labels, plural forms, title attributes, casing │ ├── HasGlobalSearch.php # Global search controls (searchability, limits, case sensitivity) │ ├── BelongsToParent.php # Parent-child resource relationships │ ├── BelongsToTenant.php # Multi-tenancy support (scoping, relationships) │ ├── WithMultipleResourceSupport.php # Multi-resource configuration (forResource method) │ └── HasPluginDefaults.php # Core defaults system implementation └── Resource/ # Traits for Resource classes ├── HasNavigation.php # Delegates navigation calls to plugin ├── HasLabels.php # Delegates label calls to plugin ├── HasGlobalSearch.php # Delegates global search calls to plugin ├── BelongsToParent.php # Delegates parent resource calls to plugin ├── BelongsToTenant.php # Delegates tenant calls to plugin └── DelegatesToPlugin.php # Core delegation mechanism ``` ## Trait Mapping & Functionality ### 1. HasNavigation (Plugin + Resource) **Plugin Trait Methods:** - `navigationLabel(string|Closure|null)` - Set navigation label - `navigationIcon(string|Closure|null)` - Set navigation icon - `activeNavigationIcon(string|Closure|null)` - Set active navigation icon - `navigationGroup(string|Closure|null)` - Set navigation group - `navigationSort(int|Closure|null)` - Set navigation sort order - `navigationBadge(string|Closure|null)` - Set navigation badge text - `navigationBadgeColor(string|array|Closure|null)` - Set badge color - `navigationBadgeTooltip(string|Closure|null)` - Set badge tooltip - `navigationParentItem(string|Closure|null)` - Set parent navigation item - `subNavigationPosition(Closure|SubNavigationPosition)` - Set sub-navigation position - `registerNavigation(bool|Closure)` - Control navigation registration **Resource Trait Methods:** - `getNavigationLabel()` - Get navigation label (delegates to plugin) - `getNavigationIcon()` - Get navigation icon (delegates to plugin) - `getActiveNavigationIcon()` - Get active navigation icon (delegates to plugin) - `getNavigationGroup()` - Get navigation group (delegates to plugin) - `getNavigationSort()` - Get navigation sort order (delegates to plugin) - `getNavigationBadge()` - Get navigation badge (delegates to plugin) - `getNavigationBadgeColor()` - Get badge color (delegates to plugin) - `getNavigationBadgeTooltip()` - Get badge tooltip (delegates to plugin) - `getNavigationParentItem()` - Get parent navigation item (delegates to plugin) - `getSubNavigationPosition()` - Get sub-navigation position (delegates to plugin) - `shouldRegisterNavigation()` - Check if navigation should be registered (delegates to plugin) ### 2. HasLabels (Plugin + Resource) **Plugin Trait Methods:** - `modelLabel(string|Closure|null)` - Set model label - `pluralModelLabel(string|Closure|null)` - Set plural model label - `recordTitleAttribute(string|Closure|null)` - Set record title attribute - `titleCaseModelLabel(bool|Closure)` - Control title case formatting **Resource Trait Methods:** - `getModelLabel()` - Get model label (delegates to plugin) - `getPluralModelLabel()` - Get plural model label (delegates to plugin) - `getRecordTitleAttribute()` - Get record title attribute (delegates to plugin) - `hasTitleCaseModelLabel()` - Check title case setting (delegates to plugin) ### 3. HasGlobalSearch (Plugin + Resource) **Plugin Trait Methods:** - `globallySearchable(bool|Closure)` - Control global searchability - `globalSearchResultsLimit(int)` - Set search results limit - `forceGlobalSearchCaseInsensitive(bool|Closure|null)` - Force case insensitive search - `splitGlobalSearchTerms(bool|Closure)` - Control term splitting **Resource Trait Methods:** - `canGloballySearch()` - Check if globally searchable (delegates to plugin) - `isGloballySearchable()` - Check if globally searchable (delegates to plugin) - `getGlobalSearchResultsLimit()` - Get search results limit (delegates to plugin) - `isGlobalSearchForcedCaseInsensitive()` - Check case sensitivity setting (delegates to plugin) - `shouldSplitGlobalSearchTerms()` - Check term splitting setting (delegates to plugin) ### 4. BelongsToParent (Plugin + Resource) **Plugin Trait Methods:** - `parentResource(string|null)` - Set parent resource class **Resource Trait Methods:** - `getParentResource()` - Get parent resource class (delegates to plugin) ### 5. BelongsToTenant (Plugin + Resource) **Plugin Trait Methods:** - `scopeToTenant(bool|Closure)` - Control tenant scoping - `tenantRelationshipName(string|Closure|null)` - Set tenant relationship name - `tenantOwnershipRelationshipName(string|Closure|null)` - Set tenant ownership relationship name **Resource Trait Methods:** - `isScopedToTenant()` - Check if scoped to tenant (delegates to plugin) - `getTenantRelationshipName()` - Get tenant relationship name (delegates to plugin) - `getTenantOwnershipRelationshipName()` - Get tenant ownership relationship name (delegates to plugin) ### 6. WithMultipleResourceSupport (Plugin Only) **Special Trait Methods:** - `forResource(string $resourceClass)` - Set context for multi-resource configuration This trait enables per-resource configuration by maintaining contextual property storage. ## Core Implementation Details ### HasPluginDefaults Trait The foundation of the 3-tier system. Key methods: - `getPropertyWithDefaults(string $property, ?string $resourceClass = null)` - Implements the 3-tier lookup - `markPropertyAsUserSet(string $property)` - Tracks user-set properties - `getPluginDefault(string $property, ?string $resourceClass = null)` - Gets plugin developer defaults ### DelegatesToPlugin Trait Handles delegation from Resource traits to Plugin traits: - `delegateToPlugin(string $traitName, string $methodName, mixed $fallback = null)` - Core delegation method - `pluginUsesTrait(object $plugin, string $traitName)` - Checks if plugin uses required trait - `getParentResult(string $methodName)` - Falls back to parent Resource implementation ### Multi-Resource Configuration When a plugin uses `WithMultipleResourceSupport`, it can configure different resources separately: ```php $plugin ->forResource(UserResource::class) ->navigationLabel('Users') ->modelLabel('User') ->forResource(PostResource::class) ->navigationLabel('Posts') ->modelLabel('Article'); ``` ## Usage Patterns ### For Plugin Developers **1. Basic Plugin Setup:** ```php 'Your Plugin', 'navigationIcon' => 'heroicon-o-puzzle-piece', 'modelLabel' => 'Item', 'pluralModelLabel' => 'Items', 'globalSearchResultsLimit' => 25, ]; } } ``` **2. Resource Setup:** ```php 'Your Plugin', 'modelLabel' => 'Item', // Resource-specific defaults 'resources' => [ UserResource::class => [ 'modelLabel' => 'User', 'navigationIcon' => 'heroicon-o-users', ], PostResource::class => [ 'modelLabel' => 'Post', 'navigationIcon' => 'heroicon-o-document-text', ], ], ]; } } ``` ### For Plugin Users **1. Basic Configuration:** ```php public function panel(Panel $panel): Panel { return $panel ->plugins([ YourPlugin::make() ->navigationLabel('Custom Label') ->navigationIcon('heroicon-o-star') ->modelLabel('Custom Item') ->globalSearchResultsLimit(30), ]); } ``` **2. Multi-Resource Configuration:** ```php YourPlugin::make() ->forResource(UserResource::class) ->navigationLabel('Users') ->modelLabel('User') ->globalSearchResultsLimit(25) ->forResource(PostResource::class) ->navigationLabel('Posts') ->modelLabel('Article') ->globalSearchResultsLimit(10) ``` **3. Dynamic Configuration with Closures:** ```php YourPlugin::make() ->navigationLabel(fn() => 'Users (' . User::count() . ')') ->navigationBadge(fn() => User::whereNull('email_verified_at')->count()) ->modelLabel(fn() => auth()->user()->isAdmin() ? 'Admin User' : 'User') ``` ## Default Resolution Examples ### Example 1: Navigation Label Resolution ```php // User sets custom label $plugin->navigationLabel('My Custom Label'); // Result: 'My Custom Label' (User Override - Priority 1) // Plugin developer sets default in getPluginDefaults() 'navigationLabel' => 'Plugin Default Label' // Result: 'Plugin Default Label' (Plugin Default - Priority 2) // No user override or plugin default // Result: '' (Filament Default - Priority 3) ``` ### Example 2: Multi-Resource Defaults ```php protected function getPluginDefaults(): array { return [ // Global default 'modelLabel' => 'Global Item', // Resource-specific defaults 'resources' => [ UserResource::class => [ 'modelLabel' => 'User Override', ], ], ]; } // For UserResource: 'User Override' (Resource-specific default) // For PostResource: 'Global Item' (Global default) ``` ## Key Features 1. **Minimal Boilerplate**: Plugin developers just add traits and optionally set defaults 2. **Consistent API**: All plugins using these traits have the same configuration interface 3. **Flexible Defaults**: Support for both global and resource-specific defaults 4. **Closure Support**: Dynamic values and conditional logic 5. **Multi-Resource Support**: Single plugin can configure multiple resources differently 6. **Backward Compatibility**: Works with existing Filament patterns 7. **Type Safety**: Full type hints and documentation 8. **Testable**: Comprehensive test suite ensuring reliability ## Testing Strategy The package includes extensive tests covering: - **Unit Tests**: Individual trait functionality - **Feature Tests**: Integration between plugin and resource traits - **Multi-Resource Tests**: Contextual configuration scenarios - **Default Resolution Tests**: 3-tier system behavior - **Edge Cases**: Missing plugins, trait detection, error handling ## Performance Considerations - **Lazy Evaluation**: Values are only computed when needed - **Trait Detection**: Efficient reflection-based trait checking - **Caching**: Plugin instances are cached by Filament - **Minimal Overhead**: Delegation adds negligible performance cost This package essentially provides a standardized way to handle plugin configuration in Filament, reducing boilerplate code while maintaining flexibility and consistency across the ecosystem.