文件生成
简介
Filament 包含许多用于生成文件的 CLI 命令。本指南说明如何自定义生成的文件。
Filament 生成的绝大多数文件是 PHP 类。Filament 使用 nette/php-generator 以编程方式生成类,而不是模板文件。好处是生成文件更灵活,这对于支持 Filament 如此多的配置选项很重要。
每类类由一个 ClassGenerator 类生成。Filament 使用的 ClassGenerator 类列表如下:
Filament\Actions\Commands\FileGenerators\ExporterClassGenerator由make:filament-exporter命令使用。Filament\Actions\Commands\FileGenerators\ImporterClassGenerator由make:filament-importer命令使用。Filament\Forms\Commands\FileGenerators\FieldClassGenerator由make:filament-form-field命令使用。Filament\Forms\Commands\FileGenerators\FormSchemaClassGenerator由make:filament-form命令使用。Filament\Forms\Commands\FileGenerators\LivewireFormComponentClassGenerator由make:filament-livewire-form命令使用。Filament\Infolists\Commands\FileGenerators\EntryClassGenerator由make:filament-infolist-entry命令使用。Filament\Commands\FileGenerators\Resources\Pages\ResourceCreateRecordPageClassGenerator由make:filament-resource与make:filament-page命令使用。Filament\Commands\FileGenerators\Resources\Pages\ResourceCustomPageClassGenerator由make:filament-resource与make:filament-page命令使用。Filament\Commands\FileGenerators\Resources\Pages\ResourceEditRecordPageClassGenerator由make:filament-resource与make:filament-page命令使用。Filament\Commands\FileGenerators\Resources\Pages\ResourceListRecordsPageClassGenerator由make:filament-resource与make:filament-page命令使用。Filament\Commands\FileGenerators\Resources\Pages\ResourceManageRecordsPageClassGenerator由make:filament-resource与make:filament-page命令使用。Filament\Commands\FileGenerators\Resources\Pages\ResourceManageRelatedRecordsPageClassGenerator由make:filament-resource与make:filament-page命令使用。Filament\Commands\FileGenerators\Resources\Pages\ResourceViewRecordPageClassGenerator由make:filament-resource与make:filament-page命令使用。Filament\Commands\FileGenerators\Resources\SchemasResourceFormSchemaClassGenerator由make:filament-resource命令使用。Filament\Commands\FileGenerators\Resources\SchemasResourceInfolistSchemaClassGenerator由make:filament-resource命令使用。Filament\Commands\FileGenerators\Resources\SchemasResourceTableClassGenerator由make:filament-resource命令使用。Filament\Commands\FileGenerators\Resources\RelationManagerClassGenerator由make:filament-relation-manager命令使用。Filament\Commands\FileGenerators\Resources\ResourceClassGenerator由make:filament-resource命令使用。Filament\Commands\FileGenerators\ClusterClassGenerator由make:filament-cluster命令使用。Filament\Commands\FileGenerators\CustomPageClassGenerator由make:filament-page命令使用。Filament\Commands\FileGenerators\PanelProviderClassGenerator由filament:install与make:filament-panel命令使用。Filament\Schemas\Commands\FileGenerators\ComponentClassGenerator由make:filament-schema-component命令使用。Filament\Schemas\Commands\FileGenerators\LivewireSchemaComponentClassGenerator由make:filament-livewire-schema命令使用。Filament\Schemas\Commands\FileGenerators\SchemaClassGenerator由make:filament-schema命令使用。Filament\Tables\Commands\FileGenerators\ColumnClassGenerator由make:filament-table-column命令使用。Filament\Tables\Commands\FileGenerators\LivewireTableComponentClassGenerator由make:filament-livewire-table命令使用。Filament\Tables\Commands\FileGenerators\TableClassGenerator由make:filament-table命令使用。Filament\Widgets\Commands\FileGenerators\ChartWidgetClassGenerator由make:filament-widget命令使用。Filament\Widgets\Commands\FileGenerators\CustomWidgetClassGenerator由make:filament-widget命令使用。Filament\Widgets\Commands\FileGenerators\StatsOverviewWidgetClassGenerator由make:filament-widget命令使用。Filament\Widgets\Commands\FileGenerators\TableWidgetClassGenerator由make:filament-widget命令使用。
Class generator 的结构
了解 class generator 的最佳方式是查看其源码。它们模式非常相似,并使用 nette/php-generator 的功能。
值得关注的方法包括:
__construct()接收传入 generator 的参数。这是你生成类时可获得的全部上下文信息。getImports()返回正在生成的类中使用的 imports。这不是完整列表;生成属性与方法时也可再添加 imports,若比事先全部提供更方便。getExtends()返回被继承类的完全限定名。addTraitsToClass()用于向正在生成的类添加 traits。会传入nette/php-generator的Class对象作为参数。addPropertiesToClass()用于向正在生成的类添加属性。会传入nette/php-generator的Class对象作为参数。add*PropertyToClass()方法用于向正在生成的类添加单个属性。会传入nette/php-generator的Class对象作为参数。通常由addPropertiesToClass()调用。addMethodsToClass()用于向正在生成的类添加方法。会传入nette/php-generator的Class对象作为参数。add*MethodToClass()方法用于向正在生成的类添加单个方法。会传入nette/php-generator的Class对象作为参数。通常由addMethodsToClass()调用。
替换 class generator
若要更改文件的生成方式,需先确定正确的 class generator(见上表)并替换它。
要替换它,创建一个继承目标 class generator 的新类。例如,若要替换 ResourceClassGenerator,可这样创建:
namespace App\Filament\Commands\FileGenerators\Resources;
use Filament\Commands\FileGenerators\Resources\ResourceClassGenerator as BaseResourceClassGenerator;
class ResourceClassGenerator extends BaseResourceClassGenerator
{
// ...
}还需在服务容器中注册绑定。可在如 AppServiceProvider 的 service provider 中完成:
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);
// ...
}
}自定义类中已有属性或方法
查看 class generator 源码时,找到要自定义的属性或方法。可在你的 class generator 中定义同名方法来覆盖。例如,下面是向 resource 类添加 $navigationIcon 属性的方法:
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);
}你可以覆盖该方法以改变行为,也可以只覆盖 configureNavigationIconProperty() 来介入属性配置。例如,将属性设为 public 而非 protected:
use Nette\PhpGenerator\Property;
protected function configureNavigationIconProperty(Property $property): void
{
$property->setPublic();
}向类添加新属性或方法
要向类添加新属性或方法,可在 addPropertiesToClass() 或 addMethodsToClass() 中完成。若要继承已有属性而非替换,请在方法开头调用 parent::addPropertiesToClass() 或 parent::addMethodsToClass()。例如,向 resource 类添加新属性:
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');
}