Version

Theme

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 the make:filament-exporter command.
  • Filament\Actions\Commands\FileGenerators\ImporterClassGenerator is used by the make:filament-importer command.
  • Filament\Forms\Commands\FileGenerators\FieldClassGenerator is used by the make:filament-form-field command.
  • Filament\Forms\Commands\FileGenerators\FormSchemaClassGenerator is used by the make:filament-form command.
  • Filament\Forms\Commands\FileGenerators\LivewireFormComponentClassGenerator is used by the make:filament-livewire-form command.
  • Filament\Infolists\Commands\FileGenerators\EntryClassGenerator is used by the make:filament-infolist-entry command.
  • Filament\Commands\FileGenerators\Resources\Pages\ResourceCreateRecordPageClassGenerator is used by the make:filament-resource and make:filament-page commands.
  • Filament\Commands\FileGenerators\Resources\Pages\ResourceCustomPageClassGenerator is used by the make:filament-resource and make:filament-page commands.
  • Filament\Commands\FileGenerators\Resources\Pages\ResourceEditRecordPageClassGenerator is used by the make:filament-resource and make:filament-page commands.
  • Filament\Commands\FileGenerators\Resources\Pages\ResourceListRecordsPageClassGenerator is used by the make:filament-resource and make:filament-page commands.
  • Filament\Commands\FileGenerators\Resources\Pages\ResourceManageRecordsPageClassGenerator is used by the make:filament-resource and make:filament-page commands.
  • Filament\Commands\FileGenerators\Resources\Pages\ResourceManageRelatedRecordsPageClassGenerator is used by the make:filament-resource and make:filament-page commands.
  • Filament\Commands\FileGenerators\Resources\Pages\ResourceViewRecordPageClassGenerator is used by the make:filament-resource and make:filament-page commands.
  • Filament\Commands\FileGenerators\Resources\SchemasResourceFormSchemaClassGenerator is used by the make:filament-resource command.
  • Filament\Commands\FileGenerators\Resources\SchemasResourceInfolistSchemaClassGenerator is used by the make:filament-resource command.
  • Filament\Commands\FileGenerators\Resources\SchemasResourceTableClassGenerator is used by the make:filament-resource command.
  • Filament\Commands\FileGenerators\Resources\RelationManagerClassGenerator is used by the make:filament-relation-manager command.
  • Filament\Commands\FileGenerators\Resources\ResourceClassGenerator is used by the make:filament-resource command.
  • Filament\Commands\FileGenerators\ClusterClassGenerator is used by the make:filament-cluster command.
  • Filament\Commands\FileGenerators\CustomPageClassGenerator is used by the make:filament-page command.
  • Filament\Commands\FileGenerators\PanelProviderClassGenerator is used by the filament:install and make:filament-panel commands.
  • Filament\Schemas\Commands\FileGenerators\ComponentClassGenerator is used by the make:filament-schema-component command.
  • Filament\Schemas\Commands\FileGenerators\LivewireSchemaComponentClassGenerator is used by the make:filament-livewire-schema command.
  • Filament\Schemas\Commands\FileGenerators\SchemaClassGenerator is used by the make:filament-schema command.
  • Filament\Tables\Commands\FileGenerators\ColumnClassGenerator is used by the make:filament-table-column command.
  • Filament\Tables\Commands\FileGenerators\LivewireTableComponentClassGenerator is used by the make:filament-livewire-table command.
  • Filament\Tables\Commands\FileGenerators\TableClassGenerator is used by the make:filament-table command.
  • Filament\Widgets\Commands\FileGenerators\ChartWidgetClassGenerator is used by the make:filament-widget command.
  • Filament\Widgets\Commands\FileGenerators\CustomWidgetClassGenerator is used by the make:filament-widget command.
  • Filament\Widgets\Commands\FileGenerators\StatsOverviewWidgetClassGenerator is used by the make:filament-widget command.
  • Filament\Widgets\Commands\FileGenerators\TableWidgetClassGenerator is used by the make: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. The Class object from nette/php-generator is passed in as a parameter.
  • addPropertiesToClass() is used to add properties to the class being generated. The Class object from nette/php-generator is passed in as a parameter.
  • add*PropertyToClass() methods are used to add a single property to the class being generated. The Class object from nette/php-generator is passed in as a parameter. They are usually called from addPropertiesToClass().
  • addMethodsToClass() is used to add methods to the class being generated. The Class object from nette/php-generator is passed in as a parameter.
  • add*MethodToClass() methods are used to add a single method to the class being generated. The Class object from nette/php-generator is passed in as a parameter. They are usually called from addMethodsToClass().

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 GitHub

Still need help? Join our Discord community or open a GitHub discussion

Previous
Enum tricks