Languages

Version

Theme

高级

文件生成

介绍

Filament 引入了许多生成文件的 CLI 命令。本文将接受如何自定义生成文件。

Filament 生成的大部分文件都是 PHP 类。Filament 使用 nette/php-generator 以编程方式生成类,而不是使用模板文件。这样做的优点是,生成的文件时有更多的灵活性,当你需要支持与 Filament 一样多的不同配置选项时,这一点非常重要。

每个类型的类都由 ClassGenerator 类生成。以下是 Filament 使用的 ClassGenerator 类列表:

  • Filament\Actions\Commands\FileGenerators\ExporterClassGeneratormake:filament-exporter 命令使用的类。
  • Filament\Actions\Commands\FileGenerators\ImporterClassGeneratormake:filament-importer 命令使用的类。
  • Filament\Forms\Commands\FileGenerators\FieldClassGeneratormake:filament-form-field 命令使用的类。
  • Filament\Forms\Commands\FileGenerators\FormSchemaClassGeneratormake:filament-form 命令使用的类。
  • Filament\Forms\Commands\FileGenerators\LivewireFormComponentClassGeneratormake:filament-livewire-form 命令使用的类。
  • Filament\Infolists\Commands\FileGenerators\EntryClassGeneratormake:filament-infolist-entry 命令使用的类。
  • Filament\Commands\FileGenerators\Resources\Pages\ResourceCreateRecordPageClassGeneratormake:filament-resourcemake:filament-page 命令使用的类。
  • Filament\Commands\FileGenerators\Resources\Pages\ResourceCustomPageClassGeneratormake:filament-resourcemake:filament-page 命令使用的类。
  • Filament\Commands\FileGenerators\Resources\Pages\ResourceEditRecordPageClassGeneratormake:filament-resourcemake:filament-page 命令使用的类。
  • Filament\Commands\FileGenerators\Resources\Pages\ResourceListRecordsPageClassGeneratormake:filament-resourcemake:filament-page 命令使用的类。
  • Filament\Commands\FileGenerators\Resources\Pages\ResourceManageRecordsPageClassGeneratormake:filament-resourcemake:filament-page 命令使用的类。
  • Filament\Commands\FileGenerators\Resources\Pages\ResourceManageRelatedRecordsPageClassGeneratormake:filament-resourcemake:filament-page 命令使用的类。
  • Filament\Commands\FileGenerators\Resources\Pages\ResourceViewRecordPageClassGeneratormake:filament-resourcemake:filament-page 命令使用的类。
  • Filament\Commands\FileGenerators\Resources\SchemasResourceFormSchemaClassGeneratormake:filament-resource 命令使用的类。
  • Filament\Commands\FileGenerators\Resources\SchemasResourceInfolistSchemaClassGeneratormake:filament-resource 命令使用的类。
  • Filament\Commands\FileGenerators\Resources\SchemasResourceTableClassGeneratormake:filament-resource 命令使用的类。
  • Filament\Commands\FileGenerators\Resources\RelationManagerClassGeneratormake:filament-relation-manager 命令使用的类。
  • Filament\Commands\FileGenerators\Resources\ResourceClassGeneratormake:filament-resource 命令使用的类。
  • Filament\Commands\FileGenerators\ClusterClassGeneratormake:filament-cluster 命令使用的类。
  • Filament\Commands\FileGenerators\CustomPageClassGeneratormake:filament-page 命令使用的类。
  • Filament\Commands\FileGenerators\PanelProviderClassGeneratorfilament:installmake:filament-panel commands.
  • Filament\Schemas\Commands\FileGenerators\ComponentClassGeneratormake:filament-schema-component 命令使用的类。
  • Filament\Schemas\Commands\FileGenerators\LivewireSchemaComponentClassGeneratormake:filament-livewire-schema 命令使用的类。
  • Filament\Schemas\Commands\FileGenerators\SchemaClassGeneratormake:filament-schema 命令使用的类。
  • Filament\Tables\Commands\FileGenerators\ColumnClassGeneratormake:filament-table-column 命令使用的类。
  • Filament\Tables\Commands\FileGenerators\LivewireTableComponentClassGeneratormake:filament-livewire-table 命令使用的类。
  • Filament\Tables\Commands\FileGenerators\TableClassGeneratormake:filament-table 命令使用的类。
  • Filament\Widgets\Commands\FileGenerators\ChartWidgetClassGeneratormake:filament-widget 命令使用的类。
  • Filament\Widgets\Commands\FileGenerators\CustomWidgetClassGeneratormake:filament-widget 命令使用的类。
  • Filament\Widgets\Commands\FileGenerators\StatsOverviewWidgetClassGeneratormake:filament-widget 命令使用的类。
  • Filament\Widgets\Commands\FileGenerators\TableWidgetClassGeneratormake:filament-widget 命令使用的类。

类生成器剖析

了解类生成器的最好方式是阅读其源码。它们都遵循非常相似的模板,并且使用了 nette/php-generator 的特性。

此处是一些需要留意的方法:

  • __construct() 接收要传入生成器的参数。这是你可以访问的作为生成类的上下文的所有信息。
  • getImports() 返回用于生成类的导入。这不是排他性列表,如果比提前提供更为容易,也可以在生成属性和方法时添加导入。
  • getExtends() 返回被继承的类的完全限定名称。
  • addTraitsToClass() 用于向正在生成的类添加 trait。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() 调用。

替换类生成器

要启用修改文件生成方式的能力,你需要识别正确的类生成器(详见上述列表)。

要对其进行替换,请创建一个新类,使之继承你想替换的类生成器。比如,如果你想替换 ResourceClassGenerator,请生成新类如下:

namespace App\Filament\Commands\FileGenerators\Resources;

use Filament\Commands\FileGenerators\Resources\ResourceClassGenerator as BaseResourceClassGenerator;

class ResourceClassGenerator extends BaseResourceClassGenerator
{
   // ...
}

你同时需要在服务容器中注册绑定它。你可以在服务提供者(如 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);
        
        // ...
    }
}

在类中自定义已有属性和方法

查看类生成器的源码时,请定位到你想要自定义的属性或者方法。你可用使用相同的名称在类生成器中定义新方法来进行重写。比如,下例是一个你可以查看的方法,它将 $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() 方法,以勾入到属性的配置。比如,将属性的 protected 改为 public

use Nette\PhpGenerator\Property;

protected function configureNavigationIconProperty(Property $property): void
{
    $property->setPublic();
}

向类中添加新属性或方法

要添加新属性或方法到类中,你可以在 addPropertiesToClass()addMethodsToClass() 中实现。要继承已有的属性,而不是替换,请确保调用在方法的起始位置调用 parent::addPropertiesToClass() 或者 parent::addMethodsToClass()。比如,下例展示了如何添加新属性到资源类中:

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 技巧