Advanced
File generation
Introduction
Filament includes many CLI commands which generate files. This guide is to explain how you can customize the generated files.
The vast majority of files that Filament generates are PHP classes. Filament uses nette/php-generator
to generate classes programmatically, instead of using template files. The advantage of this is that there is much more flexibility in the generated files, which is important when you need to support as many different configuration options as Filament has.
Each type of class is generated by a ClassGenerator
class. Here are a list of ClassGenerator
classes that Filament uses:
Filament\Actions\Commands\FileGenerators\ExporterClassGenerator
is used by themake:filament-exporter
command.Filament\Actions\Commands\FileGenerators\ImporterClassGenerator
is used by themake:filament-importer
command.Filament\Forms\Commands\FileGenerators\FieldClassGenerator
is used by themake:filament-form-field
command.Filament\Forms\Commands\FileGenerators\FormSchemaClassGenerator
is used by themake:filament-form
command.Filament\Forms\Commands\FileGenerators\LivewireFormComponentClassGenerator
is used by themake:filament-livewire-form
command.Filament\Infolists\Commands\FileGenerators\EntryClassGenerator
is used by themake:filament-infolist-entry
command.Filament\Commands\FileGenerators\Resources\Pages\ResourceCreateRecordPageClassGenerator
is used by themake:filament-resource
andmake:filament-page
commands.Filament\Commands\FileGenerators\Resources\Pages\ResourceCustomPageClassGenerator
is used by themake:filament-resource
andmake:filament-page
commands.Filament\Commands\FileGenerators\Resources\Pages\ResourceEditRecordPageClassGenerator
is used by themake:filament-resource
andmake:filament-page
commands.Filament\Commands\FileGenerators\Resources\Pages\ResourceListRecordsPageClassGenerator
is used by themake:filament-resource
andmake:filament-page
commands.Filament\Commands\FileGenerators\Resources\Pages\ResourceManageRecordsPageClassGenerator
is used by themake:filament-resource
andmake:filament-page
commands.Filament\Commands\FileGenerators\Resources\Pages\ResourceManageRelatedRecordsPageClassGenerator
is used by themake:filament-resource
andmake:filament-page
commands.Filament\Commands\FileGenerators\Resources\Pages\ResourceViewRecordPageClassGenerator
is used by themake:filament-resource
andmake:filament-page
commands.Filament\Commands\FileGenerators\Resources\SchemasResourceFormSchemaClassGenerator
is used by themake:filament-resource
command.Filament\Commands\FileGenerators\Resources\SchemasResourceInfolistSchemaClassGenerator
is used by themake:filament-resource
command.Filament\Commands\FileGenerators\Resources\SchemasResourceTableClassGenerator
is used by themake:filament-resource
command.Filament\Commands\FileGenerators\Resources\RelationManagerClassGenerator
is used by themake:filament-relation-manager
command.Filament\Commands\FileGenerators\Resources\ResourceClassGenerator
is used by themake:filament-resource
command.Filament\Commands\FileGenerators\ClusterClassGenerator
is used by themake:filament-cluster
command.Filament\Commands\FileGenerators\CustomPageClassGenerator
is used by themake:filament-page
command.Filament\Commands\FileGenerators\PanelProviderClassGenerator
is used by thefilament:install
andmake:filament-panel
commands.Filament\Schemas\Commands\FileGenerators\ComponentClassGenerator
is used by themake:filament-schema-component
command.Filament\Schemas\Commands\FileGenerators\LivewireSchemaComponentClassGenerator
is used by themake:filament-livewire-schema
command.Filament\Schemas\Commands\FileGenerators\SchemaClassGenerator
is used by themake:filament-schema
command.Filament\Tables\Commands\FileGenerators\ColumnClassGenerator
is used by themake:filament-table-column
command.Filament\Tables\Commands\FileGenerators\LivewireTableComponentClassGenerator
is used by themake:filament-livewire-table
command.Filament\Tables\Commands\FileGenerators\TableClassGenerator
is used by themake:filament-table
command.Filament\Widgets\Commands\FileGenerators\ChartWidgetClassGenerator
is used by themake:filament-widget
command.Filament\Widgets\Commands\FileGenerators\CustomWidgetClassGenerator
is used by themake:filament-widget
command.Filament\Widgets\Commands\FileGenerators\StatsOverviewWidgetClassGenerator
is used by themake:filament-widget
command.Filament\Widgets\Commands\FileGenerators\TableWidgetClassGenerator
is used by themake:filament-widget
command.
The anatomy of a class generator
The best way to learn about class generators is to look at their source code. They all follow very similar patterns, and use the features from nette/php-generator
.
Here are some methods to look out for:
__construct()
accepts the parameters that are passed into the generator. This is all the information you have access to as context for generating the class.getImports()
returns the imports that are used in the class being generated. This is not an exclusive list, and imports can be added while generating properties and methods as well, if that is easier than providing them in advance.getExtends()
returns the fully qualified name of the class being extended.addTraitsToClass()
is used to add traits to the class being generated. TheClass
object fromnette/php-generator
is passed in as a parameter.addPropertiesToClass()
is used to add properties to the class being generated. TheClass
object fromnette/php-generator
is passed in as a parameter.add*PropertyToClass()
methods are used to add a single property to the class being generated. TheClass
object fromnette/php-generator
is passed in as a parameter. They are usually called fromaddPropertiesToClass()
.addMethodsToClass()
is used to add methods to the class being generated. TheClass
object fromnette/php-generator
is passed in as a parameter.add*MethodToClass()
methods are used to add a single method to the class being generated. TheClass
object fromnette/php-generator
is passed in as a parameter. They are usually called fromaddMethodsToClass()
.
Replacing a class generator
To be able to make changes to how a file is generated, you need to identify the correct class generator (see the list above) and replace it.
To replace it, create a new class that extends the class generator you want to replace. For example, if you want to replace the ResourceClassGenerator
, create a new class like this:
namespace App\Filament\Commands\FileGenerators\Resources;
use Filament\Commands\FileGenerators\Resources\ResourceClassGenerator as BaseResourceClassGenerator;
class ResourceClassGenerator extends BaseResourceClassGenerator
{
// ...
}
You also need to register it as a binding in the service container. You can do this in a service provider such as AppServiceProvider
:
use App\Filament\Commands\FileGenerators\Resources\ResourceClassGenerator;
use Filament\Commands\FileGenerators\Resources\ResourceClassGenerator as BaseResourceClassGenerator;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function register()
{
// ...
$this->app->bind(BaseResourceClassGenerator::class, ResourceClassGenerator::class);
// ...
}
}
Customizing an existing property or method in a class
While viewing the source code of the class generator, locate the property or method you want to customize. You can override it in your class generator by simply defining a new method with the same name. For example, here is a method you can find for adding the $navigationIcon
property to a resource class:
use BackedEnum;
use Filament\Support\Icons\Heroicon;
use Nette\PhpGenerator\ClassType;
use Nette\PhpGenerator\Literal;
protected function addNavigationIconPropertyToClass(ClassType $class): void
{
$this->namespace->addUse(BackedEnum::class);
$this->namespace->addUse(Heroicon::class);
$property = $class->addProperty('navigationIcon', new Literal('Heroicon::OutlinedRectangleStack'))
->setProtected()
->setStatic()
->setType('string|BackedEnum|null');
$this->configureNavigationIconProperty($property);
}
You could override that method to change its behavior, or you could just override the configureNavigationIconProperty()
method to hook into how the property is configured. For example, make the property public
instead of protected
:
use Nette\PhpGenerator\Property;
protected function configureNavigationIconProperty(Property $property): void
{
$property->setPublic();
}
Adding a new property or method to a class
To add a new property or method to a class, you can do this in the addPropertiesToClass()
or addMethodsToClass()
methods. To inherit the existing properties instead of replacing them, make sure you call parent::addPropertiesToClass()
or parent::addMethodsToClass()
at the start of your method. For example, here is how to add a new property to a resource class:
use Nette\PhpGenerator\ClassType;
use Nette\PhpGenerator\Literal;
protected function addPropertiesToClass(ClassType $class): void
{
parent::addPropertiesToClass($class);
$class->addProperty('navigationSort', 10)
->setProtected()
->setStatic()
->setType('?int');
}
Edit on GitHubStill need help? Join our Discord community or open a GitHub discussion