timo-de-winter/filament-modifiable-plugins

A helper package for when creating packages that provide filament resources.

v2.1.3 2025-06-06 14:25 UTC

README

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

This package aims to make it easier to create filament plugins. Often when you create a plugin that publishes resources or pages you'll want to give developers the possibility of changing things like navigation sort, label, icon, etc. This plugin comes with features to modify nearly everything on a resource or page, including forms, tables, clusters, tenancy ownership, and layout (like icon, label, etc.).

Installation

You can install the package via composer:

composer require timo-de-winter/filament-modifiable-plugins

Usage for developers that use your plugin

This is an example of a plugin that may be installed that allows resources to be customized:

public function panel(Panel $panel): Panel
{
    return $panel
        ->plugins([
            UserManagementPlugin::make()
                ->navigationGroup('Settings')
                ->navigationSort(2)
                ->navigationLabel('System users')
                ->navigationIcon('heroicon-o-users')
                ->activeNavigationIcon('heroicon-m-users')
                ->pageTitle('Your users')
                ->slug('cool-users')
                ->cluster(Settings::class)
        ]);
}

Custom form & tables

Most packages that make use of customizable resources will allow you to use custom forms and tables

public function panel(Panel $panel): Panel
{
    return $panel
        ->plugins([
            UserManagementPlugin::make()
                ->form(function (Form $form) {
                    return $form->schema([
                        TextInput::make('name'),
                    ]);
                })
                // You can customize the table functions like so
                ->columns([])
                ->filters([])
                ->actions([])
                ->bulkActions([])
                // Or just override the full table like so:
                ->customTable(function (\Filament\Tables\Table $table) {
                    return $table
                        ->columns();
                })
        ]);
}

Multiple resources

When a package ships with multiple resources you can use the functions to target specific resources. When leaving the specific resource out, you will target all resources that have no specific customizer set.

public function panel(Panel $panel): Panel
{
    return $panel
        ->plugins([
            UserManagementPlugin::make()
                ->navigationGroup('Settings', UserResource::class)
                ->form(function (Form $form) {
                    return $form->schema([
                        TextInput::make('name'),
                    ]);
                }, UserResource::class),
        ]);
}

Make your plugin modifiable

When you are writing a plugin that provides one or more resources you might want to implement customizable resources as well. Below you can find an explanation of how to create a customizable resource.

Getting your plugin and resources ready

First you should add the following trait to your plugin.

use TimoDeWinter\FilamentModifiablePlugins\Concerns\CanModifyResources;

class YourPlugin implements Plugin {
    use CanModifyResources;
}

Then you should add the following trait to any of the resources that you provide and implement the getPluginId function:

use TimoDeWinter\FilamentModifiablePlugins\Concerns\CanBeModified;

class YourResource extends Resource {
    use CanBeModified;
    
    public static function getPluginId(): string
    {
        return 'my-cool-plugin';
    }
}

Developing with this plugin in mind

Since we give the developers that use your plugin the possibility to modify things like forms and tables we need to take this into account while developing resources.

Forms

To make sure that your form can be customized implement it like this:

public static function form(Form $form): Form
{
    return self::getCustomForm($form, function (Form $form) {
        return $form
            ->schema([
                // your default form schema
            ]);
    });
}

Tables

Now to make your table customizable you implement the CustomizableTable class to make customization easier.

public static function table(Table $table): Table
{
    return self::getCustomTable($table, function (CustomizableTable $table) {
        return $table
            ->defaultColumns([
                // Your default default columns
            ])
            ->defaultFilters([
                // Your default default filters
            ])
            ->defaultActions([
                // Your default default actions
            ])
            ->defaultBulkActions([
                // Your default default bulk actions
            ]);
    });
}

Custom relations

Implement custom relations like this:

public static function getRelations(): array
{
    return self::getCustomRelations([
        // Your default relations
    ]);
}

Custom pages

Implement custom pages like this:

public static function getPages(): array
{
    return self::getCustomPages([
        // Your default pages
    ]);
}

Testing

composer test

Changelog

Please see CHANGELOG for more information on what has changed recently.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

License

The MIT License (MIT). Please see License File for more information.