跳到主要内容
版本:2.x

开始

资源是用来为模型创建 CRUD 接口的静态类。它描述了管理员如何在应用内,使用表格和表单,与数据进行交互的。

新建资源

App\Models\Customer 模型新建资源:

php artisan make:filament-resource Customer

app/Filament/Resources 目录下将会生成一系列文件:

.
+-- CustomerResource.php
+-- CustomerResource
| +-- Pages
| | +-- CreateCustomer.php
| | +-- EditCustomer.php
| | +-- ListCustomers.php

新的资源类在 CustomerResource.php 中。

Pages 目录下的类用于自定义后台管理面板中和资源交互的页面。这些页面是全页Livewire组件,你可以根据需要自定义。

如果你创建的资源并没有在导航菜单中显示,很可能是因为你的模型策略viewAny() 方法并没有返回 true

简易(模态框)资源

有时候,你的模型过于简单,因此你只想在单个页面中管理记录。这种情况下你可以使用模态框进行创建,编辑和删除记录。要生成这样一个带有模态框的简易资源:

php artisan make:filament-resource Customer --simple

你的资源有一个管理(Manage)页面,该页面是一个带有模态框的列表页。

另外,你的资源类不再会有 getRelations() 方法,因为关系管理器只会在编辑页和查看页中展示,不会出现在简易资源中。其他方面则与普通资源相同。

自动生成表单和表格

如果你要节约时间,Filament 也可以基于你模型数据库的字段,为你自动生成一些表单表格

使用此功能需要安装 doctrine/dbal 包:

composer require doctrine/dbal --dev

现在你可以使用 --generate 来生成资源了:

php artisan make:filament-resource Customer --generate

注意:如果表格中含有 ENUM 字段,doctrine/dbal 将无法扫描表格且会崩溃。因此 Filament 无法据此为资源生成 schema。更多详情查阅此处

处理软删除

默认情况下,在后台面板中你不能处理删除了的记录。如果你想要在资源中添加恢复(restore)、强制删除和过滤垃圾记录等功能,可以在生成资源的时候使用 --soft-deletes 标志:

php artisan make:filament-resource Customer --soft-deletes

更多软删除的相关内容,查看此处

生成查看页面

默认情况下,资源只会生成列表页,新建页和编辑页。如果你也想要生成[查看页],使用 --view-page :

php artisan make:filament-resource Customer --view-page

记录标题

资源可以设置 $recordTitleAttribute 属性,该属性对应模型上的字段名,可以用于将其与其他模型区别开来。(译者:此处直译,意思是大体是在搜索时用以确认某条记录的唯一性。)

比如,它可以是博客文章的标题(title) 或者客户的名字(name):

protected static ?string $recordTitleAttribute = 'name';

此属性需要启用全局搜索特性才有效。

如果某个单一字段无法有效识别一条记录,你可以指定一个 Eloquent 获取器的名称。

表单

资源类中包含着一个 form() 方法,用于为新建和编辑页面创建表单:

use Filament\Forms;
use Filament\Resources\Form;

public static function form(Form $form): Form
{
return $form
->schema([
Forms\Components\TextInput::make('name')->required(),
Forms\Components\TextInput::make('email')->email()->required(),
// ...
]);
}

表单控件

schema() 方法用于定义表单结构。它是一个表单控件数组,按照显示顺序在表单中排序。

表单的可用字段包括:

查看所有可用表单控件,请查阅 表单构造器文档.

布局

表单布局完全可以自定义。我们提供了许多布局组件,它们之间可以联合使用:

要查看所有可用布局组件清单,请查阅表单构造器文档

你也可以创建你自己的完全自定义布局组件

根据情况隐藏组件

表单组件的 hiddenOn() 方法让你可以基于当前页面或操作隐藏控件。

此例中,我们在 edit 编辑页面中隐藏了 password 字段控件:

use Livewire\Component;

Forms\Components\TextInput::make('password')
->password()
->required()
->hiddenOn('edit'),

此外,有一个 visibleOn() 快捷方法用以在指定页面或操作中显示控件。

use Livewire\Component;

Forms\Components\TextInput::make('password')
->password()
->required()
->visibleOn('create'),

表格

Resource 类包含一个静态 table() 方法,用以在列表页中创建表格:

use Filament\Resources\Table;
use Filament\Tables;
use Illuminate\Database\Eloquent\Builder;

public static function table(Table $table): Table
{
return $table
->columns([
Tables\Columns\TextColumn::make('name'),
Tables\Columns\TextColumn::make('email'),
// ...
])
->filters([
Tables\Filters\Filter::make('verified')
->query(fn (Builder $query): Builder => $query->whereNotNull('email_verified_at')),
// ...
])
->actions([
Tables\Actions\EditAction::make(),
])
->bulkActions([
Tables\Actions\DeleteBulkAction::make(),
]);;
}

查阅列表页文档,可以查看表格字段过滤器操作批量操作等是怎么添加的。

关联

Filament 有多种用于管理资源关联的工具。你可以根据你的实际情况选择使用:

BelongsTo

下拉列表

Filament 有一个专门用于自动从 BelongsTo 关联加载选项的下拉列表控件:

use Filament\Forms\Components\BelongsToSelect;

BelongsToSelect::make('author_id')
->relationship('author', 'name')

关于 BelongsToSelect 的更多信息,可以查看表单文档

布局组件

表单布局组件可以用来保存子数据到关联模型,比如 BelongsTo 关联:

use Filament\Forms\Components\Fieldset;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;

Fieldset::make('Author')
->relationship('author')
->schema([
TextInput::make('name')->required(),
Textarea::make('bio'),
])

更多信息,可以查看表单文档

HasOne

布局组件

表单布局组件可以用来保存子数据到关联模型,比如 HasOne 关联:

use Filament\Forms\Components\Fieldset;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;

Fieldset::make('Metadata')
->relationship('metadata')
->schema([
TextInput::make('title'),
Textarea::make('description'),
FileUpload::make('image'),
])

更多信息,可以查看表单文档

HasMany

关联管理器

在 Filament 中,“关联管理器(Relation managers)” 允许管理员可以在不必离开资源编辑页面的情况下,展示列表、新建、编辑、删除、关联和取消关联相关记录。

相关的记录在表格中展示,可以通过按钮为每个操作打开一个模态框。

更多关于关联管理器的信息,查看相关文档

Repeater

另外,如果你想在主表单里面对关联(relationship)进行编辑,你也可以使用Repeater

use App\Models\App;
use Filament\Forms\Components\HasManyRepeater;

HasManyRepeater::make('qualifications')
->relationship('qualifications')
->schema([
// ...
])

就用户体验而言,此方案仅适用于你关联的模型只有一些有限的字段。否则,表单会变得很长。

HasManyThrough

关联管理器

在 Filament 中,“关联管理器(Relation managers)” 允许管理员可以在不离开资源编辑页面的情况下,展示列表、新建、编辑、删除相关记录。

相关的记录在表格中展示,有一些按钮用来让每个操作打开一个模态框。

更多关于关联管理器的信息,查看相关文档

BelongsToMany

多选下拉列表

Filament 可以从 BelongsToMany 关联中自动加载下拉列表:

use Filament\Forms\Components\Select;

Select::make('technologies')
->multiple()
->relationship('technologies', 'name')

更多信息,请查看表单文档

复选框列表控件

Filament 可以从 BelongsToMany 关联中自动加载复选框列表控件:

use Filament\Forms\Components\CheckboxList;

CheckboxList::make('technologies')
->relationship('technologies', 'name')

更多关于 CheckboxList 的信息,请查看表单文档.

关联管理器

在 Filament 中,“关联管理器(Relation managers)” 允许管理员可以在不离开资源编辑页面的情况下,展示列表、新建、编辑、删除、关联和取消关联相关记录。

相关的记录在表格中展示,有一些按钮用来让每个操作打开一个模态框。

更多关于关联管理器的信息,查看相关文档

MorphTo

下拉列表

Filament 可以自动从 MorphTo 关联中加载数据作为选项:

use Filament\Forms\Components\MorphToSelect;

MorphToSelect::make('commentable')
->types([
MorphToSelect\Type::make(Product::class)->titleColumnName('name'),
MorphToSelect\Type::make(Post::class)->titleColumnName('title'),
])

更多信息请查看表单构造器文档。

MorphOne

布局组件

表单布局组件可以用来保存子数据到关联模型,比如 MorphOne 关联:

use Filament\Forms\Components\Fieldset;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;

Fieldset::make('Metadata')
->relationship('metadata')
->schema([
TextInput::make('title'),
Textarea::make('description'),
FileUpload::make('image'),
])

更多信息,请查看表单文档

MorphMany

关联管理器

在 Filament 中,“关联管理器(Relation managers)” 允许管理员可以在不离开资源编辑页面的情况下,展示列表、新建、编辑、删除、关联和取消关联相关记录。

相关的记录在表格中展示,有一些按钮用来让每个操作打开一个模态框。

更多关于关联管理器的信息,查看相关文档

Repeater

另外,如果你想在主表单里面对关联(relationship)进行编辑,你也可以使用Repeater

use App\Models\App;
use Filament\Forms\Components\MorphManyRepeater;

MorphManyRepeater::make('qualifications')
->relationship('qualifications')
->schema([
// ...
])

就用户体验而言,此方案仅适用于你关联的模型只有一些有限的字段。否则,表单会变得很长。

MorphToMany

关联管理器

在 Filament 中,“关联管理器(Relation managers)” 允许管理员可以在不离开资源编辑页面的情况下,展示列表、新建、编辑、删除、关联和取消关联相关记录。

相关的记录在表格中展示,有一些按钮用来让每个操作打开一个模态框。

更多关于关联管理器的信息,查看相关文档

授权

关于授权,Filament 会监听所有应用中注册的模型策略。使用如下方法:

  • viewAny() 用于完全从导航菜单中隐藏资源,阻止用户访问任何页面。
  • create() 用于控制新建记录
  • update() 用于控制编辑记录
  • view() 用于控制查看记录
  • delete() 用于阻止单条记录被删除。deleteAny() 用于防止记录被批量删除。Filament 使用 deleteAny() 方法因为通过迭代检查 delete() 策略性能不是很好。
  • forceDelete() 用于防止单条软删除记录被强制删除。forceDeleteAny() 用于防止记录被批量强制删除。Filament 之所以使用 forceDeleteAny() 因为在多条记录中迭代检查 forceDelete() 策略性能不佳。
  • restore() 用于防止单条软删除记录被强制恢复。 restoreAny() 用于防止记录被批量强制删除。Filament 之所以使用 restoreAny() 因为在多条记录中迭代检查 restore() 策略性能不佳。
  • reorder() 用于控制记录重新排序。

资源标签

每个资源都有一个基于模型名称自动生成的资源标签(label)。比如,App\Models\Customer 模型会生成 customer 标签。

这个标签在用户界面的很多地方上使用到了,你也可以使用 $label 属性自定义:

protected static ?string $label = 'cliente';

此外,你也可以使用 getLabel() 来定义动态标签:

public static function getLabel(): string
{
return __('filament::resources/customer.label');
}

复数标签

每个资源同时也有一个基于标签自动生成的“复数标签(plural label)”。比如,customer 标签会生成 customers 复数标签。

你也可以使用 $pluralLabel 属性自定义复数标签:

protected static ?string $pluralLabel = 'clientes';

此外,你也可以使用 getPluralLabel() 来定义动态复数标签:

public static function getPluralLabel(): string
{
return __('filament::resources/customer.plural_label');
}

导航

Filament 会使用复数标签自动为资源生成一个导航菜单项。

如果你想自定义导航菜单,可以使用 $navigationLabel 属性:

protected static ?string $navigationLabel = 'Mis Clientes';

此外,你也可以使用 getNavigationLabel() 方法来定义动态复数标签:

public static function getNavigationLabel(): string
{
return __('filament::resources/customer.navigation_label');
}

图标

$navigationIcon 属性支持任何Blade模板组件名。默认情况下,Filament 安装了Blade Heroicons V1包,你可以开箱即用地使用Heroicon V1的图标名。除此之外,你也可以创建你自己自定义的ICON组件或者安装其他图标库。

protected static ?string $navigationIcon = 'heroicon-o-user-group';

此外,你可以在 getNavigationIcon() 方法中设置动态导航图标:

public static function getNavigationIcon(): string
{
return 'heroicon-o-user-group';
}

导航菜单排序

$navigationSort 属性让你可以指定导航菜单项排列顺序:

protected static ?int $navigationSort = 2;

此外,你也可以在 getNavigaionSort() 方法中动态设置导航排序:

public static function getNavigationSort(): ?int
{
return 2;
}

导航菜单分组

你可以通过 $navigationGroup 属性对导航菜单进行分组:

protected static ?string $navigationGroup = 'Shop';

此外,你也可以使用 getNavigationGroup() 方法设置分组动态标签:

protected static function getNavigationGroup(): ?string
{
return return __('filament::navigation.groups.shop');
}

自定义 Eloquent 查询

在 Filament 中,每个资源模型的查询都会从 getEloquentQuery() 方法开始。

因此,可以很容易使用你自己的模型范围(scope)查询。你可以在后台面板中用它来实现多租户(multi-tenancy)特性。

禁用全局范围查询

默认情况下,Filament 会监听所有注册到模型的全局范围查询。不过,如果你想要获取比如软删除记录时,这可能不是理想的方案。

要解决此问题,你可以重写 getEloquentQuery() 方法:

public static function getEloquentQuery(): Builder
{
return parent::getEloquentQuery()->withoutGlobalScopes();
}

此外,你也可以移除特定的全局范围查询:

public static function getEloquentQuery(): Builder
{
return parent::getEloquentQuery()->withoutGlobalScopes([ActiveScope::class]);
}

更多关于移除全局范围查询的信息可查阅Laravel文档

自定义 URL slug

默认请胯下,Filament 会根据模型名称生成一个资源URL。你可以在资源上设置 $slug 属性来自定义:

protected static ?string $slug = 'pending-orders';

Multi-tenancy

多租户(Multi-tenancy),简单地说,就是用户拥有记录,并且只能获取到他们自己的记录。(译者注:让多用户在共用程序组件之时,仍确保各用户见数据的隔离性。)

从头开始实现简单多租户技术

简单的多租户(multi-tenancy)策略在 Filament 中很容易设置。

首先,通过 getEloquentQuery() 方法为每个资源限定基础 Eloquent 查询范围

public static function getEloquentQuery(): Builder
{
return parent::getEloquentQuery()->whereBelongsTo(auth()->user());
}

此例中,使用 whereBelongsTo() 来限定属于当前认证用户的记录。此外,你可以使用任何你想用的 Eloquent 方法,包括手动的 where() 查询,或者scope范围查询

最好,如果要让新建的记录附加到当前用户上。最简单的办法是使用模型观察者

public function creating(Post $post): void
{
$post->user()->associate(auth()->user());
}

stancl/tenancy

要在 Filament 中使用 stancl/tenancy,你只需要添加 InitializeTenancyByDomain::class 中间件到 LivewireFilament 配置文件即可:

use Stancl\Tenancy\Middleware\InitializeTenancyByDomain;

'middleware' => [
// ...
'base' => [
// ...
InitializeTenancyByDomain::class
],
],

删除页面

如果你要从你的资源(resource)中删除一个页面,你只需要删除资源 Pages 目录下的对应文件,以及它在 getPages() 方法下的入口。

比如,你有一个资源不想让任何人添加记录。删除 Create 页面文件,然后在getPages()中移除:

public static function getPages(): array
{
return [
'index' => Pages\ListCustomers::route('/'),
'edit' => Pages\EditCustomer::route('/{record}/edit'),
];
}